From db595d0b539f06a178dc4bda86e7808cc557b876 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Thu, 2 Jan 2020 00:31:29 +0100 Subject: [PATCH] Structs with array members finally working. However import improvements remain regarding global initializers and unnecessary unwinding of constant structs. --- ...deref_pbuc1=_deref_pbuc2_memcpy_vbuxx.asm} | 0 ..._deref_pbuc1=_deref_pbuc2_memcpy_vbuyy.asm | 5 + .../java/dk/camelot64/kickc/Compiler.java | 1 + .../AsmFragmentInstanceSpecFactory.java | 2 +- .../kickc/model/StructUnwinding.java | 19 +- .../model/types/SymbolTypeInference.java | 2 + .../kickc/passes/Pass1ConstantifyRValue.java | 50 + .../kickc/passes/Pass1UnwindStructValues.java | 277 +- .../dk/camelot64/kickc/test/TestPrograms.java | 4 +- .../ref/complex/clearscreen/clearscreen.asm | 75 +- .../ref/complex/clearscreen/clearscreen.cfg | 10 +- .../ref/complex/clearscreen/clearscreen.log | 690 ++-- .../ref/complex/clearscreen/clearscreen.sym | 53 +- .../ref/complex/splines/truetype-splines.log | 228 +- src/test/ref/declared-memory-var-4.asm | 21 +- src/test/ref/declared-memory-var-4.cfg | 6 +- src/test/ref/declared-memory-var-4.log | 190 +- src/test/ref/declared-memory-var-4.sym | 1 + src/test/ref/sizeof-struct.log | 12 +- src/test/ref/struct-0.log | 4 +- src/test/ref/struct-1.log | 8 +- src/test/ref/struct-11.asm | 319 +- src/test/ref/struct-11.cfg | 178 +- src/test/ref/struct-11.log | 3625 +++-------------- src/test/ref/struct-11.sym | 144 +- src/test/ref/struct-12.asm | 41 +- src/test/ref/struct-12.cfg | 10 +- src/test/ref/struct-12.log | 388 +- src/test/ref/struct-12.sym | 32 +- src/test/ref/struct-13.log | 4 +- src/test/ref/struct-15.log | 4 +- src/test/ref/struct-17.log | 4 +- src/test/ref/struct-19.log | 4 +- src/test/ref/struct-2.log | 8 +- src/test/ref/struct-20.log | 4 +- src/test/ref/struct-23.log | 4 +- src/test/ref/struct-24.log | 4 +- src/test/ref/struct-26.asm | 8 +- src/test/ref/struct-26.log | 36 +- src/test/ref/struct-27.asm | 26 + src/test/ref/struct-27.cfg | 21 + src/test/ref/struct-27.log | 346 ++ src/test/ref/struct-27.sym | 13 + src/test/ref/struct-28.asm | 25 + src/test/ref/struct-28.cfg | 21 + src/test/ref/struct-28.log | 344 ++ src/test/ref/struct-28.sym | 13 + src/test/ref/struct-3.log | 4 +- src/test/ref/struct-4.log | 4 +- src/test/ref/struct-5.log | 4 +- src/test/ref/struct-6.log | 4 +- src/test/ref/struct-8.log | 4 +- src/test/ref/struct-9.log | 8 +- src/test/ref/struct-ptr-10.log | 13 +- src/test/ref/struct-ptr-11.log | 7 +- src/test/ref/struct-ptr-17.log | 4 +- src/test/ref/struct-ptr-18.log | 35 +- src/test/ref/struct-ptr-34.asm | 43 +- src/test/ref/struct-ptr-34.cfg | 6 +- src/test/ref/struct-ptr-34.log | 280 +- src/test/ref/struct-ptr-34.sym | 24 +- src/test/ref/struct-ptr-9.log | 14 +- 62 files changed, 2963 insertions(+), 4775 deletions(-) rename src/main/fragment/mos6502-common/{_deref_pbuc1=_deref_pbuc2_memcpy__vbuxx.asm => _deref_pbuc1=_deref_pbuc2_memcpy_vbuxx.asm} (100%) create mode 100644 src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy_vbuyy.asm create mode 100644 src/main/java/dk/camelot64/kickc/passes/Pass1ConstantifyRValue.java create mode 100644 src/test/ref/struct-27.asm create mode 100644 src/test/ref/struct-27.cfg create mode 100644 src/test/ref/struct-27.log create mode 100644 src/test/ref/struct-27.sym create mode 100644 src/test/ref/struct-28.asm create mode 100644 src/test/ref/struct-28.cfg create mode 100644 src/test/ref/struct-28.log create mode 100644 src/test/ref/struct-28.sym diff --git a/src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy__vbuxx.asm b/src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy_vbuxx.asm similarity index 100% rename from src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy__vbuxx.asm rename to src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy_vbuxx.asm diff --git a/src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy_vbuyy.asm b/src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy_vbuyy.asm new file mode 100644 index 000000000..282cdf4cf --- /dev/null +++ b/src/main/fragment/mos6502-common/_deref_pbuc1=_deref_pbuc2_memcpy_vbuyy.asm @@ -0,0 +1,5 @@ +!: +lda {c2}-1,y +sta {c1}-1,y +dey +bne !- \ 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 bca2ba9ab..ff79fd7ec 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -190,6 +190,7 @@ public class Compiler { new Pass1PointerSizeofFix(program).execute(); // After this point in the code all pointer math is byte-based new PassNSizeOfSimplification(program).execute(); // Needed to eliminate sizeof() referencing pointer value variables + new Pass1ConstantifyRValue(program).execute(); new Pass1UnwindStructVariables(program).execute(); new Pass1UnwindStructValues(program).execute(); new PassNStructPointerRewriting(program).execute(); diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java index 5519453c6..5f74295fa 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java @@ -382,7 +382,7 @@ public class AsmFragmentInstanceSpecFactory { SymbolType fixedIntegerType = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(sizeConst, program.getScope()); sizeConst = new ConstantCastValue(fixedIntegerType, sizeConst); } - return bind(memcpyValue.getSource()) + "_memcpy_" + "_" + bind(sizeConst); + return bind(memcpyValue.getSource()) + "_memcpy_" + bind(sizeConst); } throw new RuntimeException("Binding of value type not supported " + value.toString(program)); } diff --git a/src/main/java/dk/camelot64/kickc/model/StructUnwinding.java b/src/main/java/dk/camelot64/kickc/model/StructUnwinding.java index 634b68253..33b174ec6 100644 --- a/src/main/java/dk/camelot64/kickc/model/StructUnwinding.java +++ b/src/main/java/dk/camelot64/kickc/model/StructUnwinding.java @@ -4,8 +4,7 @@ import dk.camelot64.kickc.model.symbols.ArraySpec; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.StructDefinition; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.values.RValue; -import dk.camelot64.kickc.model.values.SymbolVariableRef; +import dk.camelot64.kickc.model.values.*; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -80,6 +79,12 @@ public class StructUnwinding { public ArraySpec getArraySpec(String memberName) { return structDefinition.getMember(memberName).getArraySpec(); } + + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + throw new RuntimeException("TODO: Implement!"); + } + } /** Information about how members of an struct Lvalue is unwound. */ @@ -114,5 +119,15 @@ public class StructUnwinding { * @return The array nature of the member */ ArraySpec getArraySpec(String memberName); + + /** + * Get unwinding value to use as RValue when for copying/setting an array member value + * @param memberName The name of the member + * @param scope The program scope + * @param arraySize The declared size of the array + * @return The value to use as RValue + */ + RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize); + } } diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java index 7199b042c..06fe5be5d 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java @@ -23,6 +23,8 @@ public class SymbolTypeInference { } else if(rValue instanceof Symbol) { Symbol rSymbol = (Symbol) rValue; type = rSymbol.getType(); + } else if(rValue instanceof LvalueIntermediate) { + return inferType(symbols, ((LvalueIntermediate) rValue).getVariable()); } else if(rValue instanceof ConstantInteger) { return ((ConstantInteger) rValue).getType(symbols); } else if(rValue instanceof ConstantString) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ConstantifyRValue.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ConstantifyRValue.java new file mode 100644 index 000000000..d50a58676 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ConstantifyRValue.java @@ -0,0 +1,50 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Initializers; +import dk.camelot64.kickc.model.Program; +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.SymbolTypeStruct; +import dk.camelot64.kickc.model.values.ConstantValue; +import dk.camelot64.kickc.model.values.RValue; + +/** + * Constantify all assignment RValues that are structs + */ +public class Pass1ConstantifyRValue extends Pass2SsaOptimization { + + public Pass1ConstantifyRValue(Program program) { + super(program); + } + + @Override + public boolean step() { + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) statement; + if(assignment.getOperator()==null) { + SymbolType lValueType = SymbolTypeInference.inferType(getProgram().getScope(), assignment.getlValue()); + RValue rValue = assignment.getrValue2(); + if(!(rValue instanceof ConstantValue) && lValueType instanceof SymbolTypeStruct) { + // TODO: Constantify all R-Values? + Initializers.ValueTypeSpec lValueTypeSpec = new Initializers.ValueTypeSpec(lValueType, null); + RValue rValueConstantified = Initializers.constantify(rValue, lValueTypeSpec, getProgram(), assignment.getSource()); + if(!rValue.equals(rValueConstantified)) { + assignment.setrValue2(rValueConstantified); + getLog().append("Constantified RValue "+assignment.toString(getProgram(), false)); + } + } + + } + } + } + } + return false; + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java index 1276b4148..783914a14 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java @@ -193,131 +193,81 @@ public class Pass1UnwindStructValues extends Pass1Base { * @param currentBlock The current code block */ private boolean unwindAssignment(StatementAssignment assignment, ListIterator stmtIt, ControlFlowBlock currentBlock) { - StructUnwinding.StructMemberUnwinding memberUnwinding = getStructMemberUnwinding(assignment.getlValue(), assignment, stmtIt, currentBlock); + LValue lValue = assignment.getlValue(); + StructUnwinding.StructMemberUnwinding lValueUnwinding = getStructMemberUnwinding(lValue, assignment, stmtIt, currentBlock); - if(memberUnwinding == null) { + if(lValueUnwinding == null) { return false; - } else if(memberUnwinding == POSTPONE_UNWINDING) { + } else if(lValueUnwinding == POSTPONE_UNWINDING) { return true; } if(assignment.getOperator() == null) { + SymbolTypeStruct lValueStructType = (SymbolTypeStruct) SymbolTypeInference.inferType(getScope(), lValue); RValue rValue = assignment.getrValue2(); - if(rValue instanceof CastValue) { - rValue = ((CastValue) rValue).getValue(); - } - if(rValue instanceof StructZero && assignment.getlValue() instanceof VariableRef) { - // Zero-initializing a struct - unwind to assigning zero to each member! - List membersUnwound = new ArrayList<>(); - stmtIt.previous(); - for(String memberName : memberUnwinding.getMemberNames()) { - if(memberUnwinding.getArraySpec(memberName) != null) { - // Member is an array - return pointer to array start - RValue memberVarPointer = memberUnwinding.getMemberUnwinding(memberName, getScope()); - membersUnwound.add(memberVarPointer); - LValue memberVarRef = new PointerDereferenceSimple(memberVarPointer); - StatementSource statementSource = assignment.getSource(); - MemsetValue memClearValue = new MemsetValue(memberUnwinding.getArraySpec(memberName).getArraySize()); - Statement initStmt = new StatementAssignment(memberVarRef, memClearValue, assignment.isInitialAssignment(), statementSource, Comment.NO_COMMENTS); - stmtIt.add(initStmt); - getLog().append("Adding struct value member variable default initializer " + initStmt.toString(getProgram(), false)); - } else { - // Member is not an array - return deref(pointer to element) - LValue memberVarRef = (LValue) memberUnwinding.getMemberUnwinding(memberName, getScope()); - membersUnwound.add(memberVarRef); - StatementSource statementSource = assignment.getSource(); - SymbolType memberType = memberUnwinding.getMemberType(memberName); - ArraySpec memberArraySpec = memberUnwinding.getArraySpec(memberName); - RValue initValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(memberType, memberArraySpec), statementSource); - Statement initStmt = new StatementAssignment(memberVarRef, initValue, assignment.isInitialAssignment(), statementSource, Comment.NO_COMMENTS); - stmtIt.add(initStmt); - getLog().append("Adding struct value member variable default initializer " + initStmt.toString(getProgram(), false)); - } - } - stmtIt.next(); - if(assignment.getlValue() instanceof VariableRef) { - SymbolTypeStruct structType = (SymbolTypeStruct) SymbolTypeInference.inferType(getScope(), assignment.getlValue()); - assignment.setrValue2(new StructUnwoundPlaceholder(structType, membersUnwound)); - } else { - stmtIt.remove(); - } - return true; - } else if(rValue instanceof ValueList) { - // Initializing struct with a value list - unwind to assigning each member with a value from the list - ValueList valueList = (ValueList) rValue; - if(memberUnwinding.getMemberNames().size() != valueList.getList().size()) { - throw new CompileError("Struct initialization list has wrong size. Need " + memberUnwinding.getMemberNames().size() + " got " + valueList.getList().size(), assignment); - } - stmtIt.previous(); - List membersUnwound = new ArrayList<>(); - int idx = 0; - for(String memberName : memberUnwinding.getMemberNames()) { - LValue memberLvalue = (LValue) memberUnwinding.getMemberUnwinding(memberName, getScope()); - membersUnwound.add(memberLvalue); - Statement initStmt = new StatementAssignment(memberLvalue, valueList.getList().get(idx++), assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS); - stmtIt.add(initStmt); - getLog().append("Adding struct value list initializer " + initStmt.toString(getProgram(), false)); - } - stmtIt.next(); - if(assignment.getlValue() instanceof VariableRef) { - SymbolTypeStruct structType = (SymbolTypeStruct) SymbolTypeInference.inferType(getScope(), assignment.getlValue()); - assignment.setrValue2(new StructUnwoundPlaceholder(structType, membersUnwound)); - } else { - stmtIt.remove(); - } - return true; - } else { - if(rValue instanceof StructUnwoundPlaceholder) - return false; - SymbolTypeStruct structType = (SymbolTypeStruct) SymbolTypeInference.inferType(getScope(), assignment.getlValue()); - SymbolType sourceType = SymbolTypeInference.inferType(getScope(), rValue); - if(sourceType.equals(structType)) { - // Copying a struct - unwind to assigning each member! - StructUnwinding.StructMemberUnwinding sourceMemberUnwinding = getStructMemberUnwinding(rValue, assignment, stmtIt, currentBlock); - if(sourceMemberUnwinding == null) { - throw new CompileError("Incompatible struct assignment " + assignment.toString(getProgram(), false), assignment); - } else if(sourceMemberUnwinding == POSTPONE_UNWINDING) { - return true; - } else { - List membersUnwound = new ArrayList<>(); - stmtIt.previous(); - for(String memberName : memberUnwinding.getMemberNames()) { - if(memberUnwinding.getArraySpec(memberName)!=null) { - RValue assignedMemberVarPointer = memberUnwinding.getMemberUnwinding(memberName, getScope()); - LValue assignedMemberVarRef = new PointerDereferenceSimple(assignedMemberVarPointer); - RValue sourceMemberVarPointer = sourceMemberUnwinding.getMemberUnwinding(memberName, getScope()); - LValue sourceMemberVarRef = new PointerDereferenceSimple(sourceMemberVarPointer); - ConstantValue arraySize = memberUnwinding.getArraySpec(memberName).getArraySize(); - membersUnwound.add(assignedMemberVarPointer); - Statement copyStmt = new StatementAssignment(assignedMemberVarRef, new MemcpyValue(sourceMemberVarRef, arraySize), assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS); - stmtIt.add(copyStmt); - getLog().append("Adding struct value member variable copy " + copyStmt.toString(getProgram(), false)); - - } else { - LValue assignedMemberVarRef = (LValue) memberUnwinding.getMemberUnwinding(memberName, getScope()); - RValue sourceMemberVarRef = sourceMemberUnwinding.getMemberUnwinding(memberName, getScope()); - membersUnwound.add(assignedMemberVarRef); - Statement copyStmt = new StatementAssignment(assignedMemberVarRef, sourceMemberVarRef, assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS); - stmtIt.add(copyStmt); - getLog().append("Adding struct value member variable copy " + copyStmt.toString(getProgram(), false)); - } - } - stmtIt.next(); - if(assignment.getlValue() instanceof VariableRef) { - assignment.setrValue2(new StructUnwoundPlaceholder(structType, membersUnwound)); - } else { - stmtIt.remove(); - } - return true; - } - } else { + if(rValue instanceof StructUnwoundPlaceholder) + return false; + SymbolType rValueType = SymbolTypeInference.inferType(getScope(), rValue); + boolean initialAssignment = assignment.isInitialAssignment(); + StatementSource source = assignment.getSource(); + if(rValueType.equals(lValueStructType)) { + StructUnwinding.StructMemberUnwinding rValueUnwinding = getStructMemberUnwinding(rValue, assignment, stmtIt, currentBlock); + if(rValueUnwinding == null) { throw new CompileError("Incompatible struct assignment " + assignment.toString(getProgram(), false), assignment); } + if(rValueUnwinding == POSTPONE_UNWINDING) + return true; + StructUnwoundPlaceholder unwoundPlaceholder = unwindAssignment(lValueStructType, lValueUnwinding, rValueUnwinding, stmtIt, initialAssignment, source); + if(lValue instanceof VariableRef) { + assignment.setrValue2(unwoundPlaceholder); + } else { + stmtIt.remove(); + } + return true; } } throw new CompileError("Incompatible struct assignment " + assignment.toString(getProgram(), false), assignment); } + /** + * Unwind assignment of members from an RValue to an LValue + * + * @param structType The type of struct being unwound + * @param lValueUnwinding The member unwinding of the LValue + * @param rValueUnwinding The member unwinding of the RValue + * @param stmtIt Statement iterator used for adding unwound assignment statements (before the current statement) + * @param initialAssignment Is this the initial assignment + * @param source The statement source + * @return Struct unwound placeholder describing the performed unwinding + */ + private StructUnwoundPlaceholder unwindAssignment(SymbolTypeStruct structType, StructUnwinding.StructMemberUnwinding lValueUnwinding, StructUnwinding.StructMemberUnwinding rValueUnwinding, ListIterator stmtIt, boolean initialAssignment, StatementSource source) { + List lValueUnwoundPlaceholder = new ArrayList<>(); + stmtIt.previous(); + for(String memberName : lValueUnwinding.getMemberNames()) { + if(lValueUnwinding.getArraySpec(memberName) != null) { + // Unwinding an array struct member + RValue lValueMemberVarPointer = lValueUnwinding.getMemberUnwinding(memberName, getScope()); + LValue lValueMemberVarRef = new PointerDereferenceSimple(lValueMemberVarPointer); + ConstantValue arraySize = lValueUnwinding.getArraySpec(memberName).getArraySize(); + RValue rValueArrayUnwinding = rValueUnwinding.getMemberArrayUnwinding(memberName, getScope(), arraySize); + lValueUnwoundPlaceholder.add(lValueMemberVarPointer); + Statement copyStmt = new StatementAssignment(lValueMemberVarRef, rValueArrayUnwinding, initialAssignment, source, Comment.NO_COMMENTS); + stmtIt.add(copyStmt); + getLog().append("Adding struct value member variable copy " + copyStmt.toString(getProgram(), false)); + } else { + // Unwinding a non-array struct member + LValue lValueMemberVarRef = (LValue) lValueUnwinding.getMemberUnwinding(memberName, getScope()); + RValue rValueMemberVarRef = rValueUnwinding.getMemberUnwinding(memberName, getScope()); + lValueUnwoundPlaceholder.add(lValueMemberVarRef); + Statement copyStmt = new StatementAssignment(lValueMemberVarRef, rValueMemberVarRef, initialAssignment, source, Comment.NO_COMMENTS); + stmtIt.add(copyStmt); + getLog().append("Adding struct value member variable copy " + copyStmt.toString(getProgram(), false)); + } + } + stmtIt.next(); + return new StructUnwoundPlaceholder(structType, lValueUnwoundPlaceholder); + } + /** * Examine a value - and if it represents a struct get the unwinding information for the struct members * @@ -332,24 +282,36 @@ public class Pass1UnwindStructValues extends Pass1Base { SymbolType valueType = SymbolTypeInference.inferType(getScope(), value); if(valueType instanceof SymbolTypeStruct) { SymbolTypeStruct structType = (SymbolTypeStruct) valueType; + StructDefinition structDefinition = structType.getStructDefinition(getScope()); + if(value instanceof CastValue && ((CastValue) value).getValue() instanceof ValueList) { + ValueList valueList = (ValueList) ((CastValue) value).getValue(); + int numMembers = structDefinition.getAllVars(false).size(); + if(numMembers != valueList.getList().size()) { + throw new CompileError("Struct initialization list has wrong size. Need " + numMembers + " got " + valueList.getList().size(), currentStmt); + } + return new StructMemberUnwindingValueList(valueList, structDefinition); + } + if(value instanceof CastValue) + value = ((CastValue) value).getValue(); + if(value instanceof VariableRef) { Variable variable = getScope().getVariable((VariableRef) value); if(variable.isStructUnwind()) { StructUnwinding structUnwinding = getProgram().getStructUnwinding(); return structUnwinding.getVariableUnwinding((VariableRef) value); } else if(variable.isStructClassic()) { - return new StructVariableMemberUnwinding(variable, structType.getStructDefinition(getScope()), currentBlock, stmtIt, currentStmt); + return new StructVariableMemberUnwinding(variable, structDefinition, currentBlock, stmtIt, currentStmt); } } else if(value instanceof StructMemberRef && ((StructMemberRef) value).getStruct() instanceof VariableRef) { return POSTPONE_UNWINDING; } else if(value instanceof PointerDereferenceSimple) { - return new StructMemberUnwindingPointerDerefSimple((PointerDereferenceSimple) value, structType.getStructDefinition(getScope()), stmtIt, currentBlock, currentStmt); + return new StructMemberUnwindingPointerDerefSimple((PointerDereferenceSimple) value, structDefinition, stmtIt, currentBlock, currentStmt); } else if(value instanceof PointerDereferenceIndexed) { - return new StructMemberUnwindingPointerDerefIndexed((PointerDereferenceIndexed) value, structType.getStructDefinition(getScope()), stmtIt, currentBlock, currentStmt); + return new StructMemberUnwindingPointerDerefIndexed((PointerDereferenceIndexed) value, structDefinition, stmtIt, currentBlock, currentStmt); } else if(value instanceof ConstantStructValue) { - return new StructMemberUnwindingConstantValue((ConstantStructValue) value, structType.getStructDefinition(getScope())); + return new StructMemberUnwindingConstantValue((ConstantStructValue) value, structDefinition); } else if(value instanceof StructZero) { - return new StructMemberUnwindingZero((StructZero) value, structType.getStructDefinition(getScope())); + return new StructMemberUnwindingZero((StructZero) value, structDefinition); } else { throw new InternalError("Struct unwinding not implemented for " + value.toString(getProgram())); } @@ -379,6 +341,11 @@ public class Pass1UnwindStructValues extends Pass1Base { public ArraySpec getArraySpec(String memberName) { return null; } + + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + return null; + } }; /** Unwinding for a simple pointer deref to a struct. */ @@ -430,6 +397,12 @@ public class Pass1UnwindStructValues extends Pass1Base { public ArraySpec getArraySpec(String memberName) { return structDefinition.getMember(memberName).getArraySpec(); } + + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + throw new RuntimeException("TODO: Implement!"); + } + } /** Unwinding for a indexed pointer deref to a struct. */ @@ -482,6 +455,11 @@ public class Pass1UnwindStructValues extends Pass1Base { return structDefinition.getMember(memberName).getArraySpec(); } + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + throw new RuntimeException("TODO: Implement!"); + } + } /** Unwinding for constant struct value. */ @@ -520,6 +498,18 @@ public class Pass1UnwindStructValues extends Pass1Base { return structDefinition.getMember(memberName).getArraySpec(); } + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + // Create a constant variable holding the array + String constName = scope.allocateIntermediateVariableName(); + Variable member = structDefinition.getMember(memberName); + SymbolType memberType = member.getType(); + ConstantValue constValue = constantStructValue.getValue(member.getRef()); + Variable constVar = Variable.createConstant(constName, memberType, scope, new ArraySpec(arraySize), constValue, Scope.SEGMENT_DATA_DEFAULT); + scope.add(constVar); + return new MemcpyValue(new PointerDereferenceSimple(constVar.getRef()), arraySize); + } + } /** Unwinding for a struct value with C-classic memory layout. */ @@ -582,6 +572,13 @@ public class Pass1UnwindStructValues extends Pass1Base { return structDefinition.getMember(memberName).getArraySpec(); } + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + RValue rValueMemberVarPointer = getMemberUnwinding(memberName, scope); + LValue rValueMemberVarRef = new PointerDereferenceSimple(rValueMemberVarPointer); + return new MemcpyValue(rValueMemberVarRef, arraySize); + } + } /** Unwinding for StructZero */ @@ -619,5 +616,53 @@ public class Pass1UnwindStructValues extends Pass1Base { return structDefinition.getMember(memberName).getArraySpec(); } + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + return new MemsetValue(arraySize); + } + + } + + /** Unwinding for ValueList. */ + private static class StructMemberUnwindingValueList implements StructUnwinding.StructMemberUnwinding { + + StructDefinition structDefinition; + ValueList valueList; + + public StructMemberUnwindingValueList(ValueList valueList, StructDefinition structDefinition) { + this.valueList = valueList; + this.structDefinition = structDefinition; + } + + @Override + public List getMemberNames() { + Collection structMemberVars = structDefinition.getAllVariables(false); + ArrayList memberNames = new ArrayList<>(); + for(Variable structMemberVar : structMemberVars) { + memberNames.add(structMemberVar.getLocalName()); + } + return memberNames; + } + + @Override + public RValue getMemberUnwinding(String memberName, ProgramScope programScope) { + int memberIndex = getMemberNames().indexOf(memberName); + return valueList.getList().get(memberIndex); + } + + @Override + public SymbolType getMemberType(String memberName) { + return structDefinition.getMember(memberName).getType(); + } + + @Override + public ArraySpec getArraySpec(String memberName) { + return structDefinition.getMember(memberName).getArraySpec(); + } + + @Override + public RValue getMemberArrayUnwinding(String memberName, ProgramScope scope, ConstantValue arraySize) { + throw new RuntimeException("TODO: Implement!"); + } } } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 1dd1fef56..d2313f9c9 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -1129,12 +1129,12 @@ public class TestPrograms { @Test public void testStruct28() throws IOException, URISyntaxException { - compileAndCompare("struct-28", log()); + compileAndCompare("struct-28"); } @Test public void testStruct27() throws IOException, URISyntaxException { - compileAndCompare("struct-27", log()); + compileAndCompare("struct-27"); } @Test diff --git a/src/test/ref/complex/clearscreen/clearscreen.asm b/src/test/ref/complex/clearscreen/clearscreen.asm index cd67eecfd..da895e2b8 100644 --- a/src/test/ref/complex/clearscreen/clearscreen.asm +++ b/src/test/ref/complex/clearscreen/clearscreen.asm @@ -95,8 +95,7 @@ __b1: main: { .label dst = 3 .label src = $1c - .label i = 2 - .label center_y = $b + .label center_y = $1e lda.z SCREEN_DIST sta.z init_angle_screen.screen lda.z SCREEN_DIST+1 @@ -118,39 +117,39 @@ main: { lda.z src cmp #$3c sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,x lda.z freeIdx sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_ID,x @@ -477,11 +476,11 @@ getCharToProcess: { .label screen_line = $1c .label dist_line = 3 .label y = 2 - .label return_x = $17 - .label return_y = $b - .label closest_dist = $12 - .label closest_x = $17 - .label closest_y = $b + .label return_x = $12 + .label return_y = $17 + .label closest_dist = $b + .label closest_x = $12 + .label closest_y = $17 .label __12 = $1a .label __13 = $18 lda.z SCREEN_COPY @@ -670,7 +669,7 @@ init_angle_screen: { .label ang_w = $1e .label x = $12 .label xb = $17 - .label y = 2 + .label y = $b lda.z screen clc adc #<$28*$c diff --git a/src/test/ref/complex/clearscreen/clearscreen.cfg b/src/test/ref/complex/clearscreen/clearscreen.cfg index 6c2290ad5..cf80b39c1 100644 --- a/src/test/ref/complex/clearscreen/clearscreen.cfg +++ b/src/test/ref/complex/clearscreen/clearscreen.cfg @@ -39,10 +39,10 @@ main::@3: scope:[main] from main::@1 main::@3 [17] (byte~) main::$22 ← (byte~) main::$21 << (byte) 1 [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 - [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 - [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 - [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 - [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 + [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 + [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 + [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 + [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 @@ -160,7 +160,7 @@ startProcessing::@7: scope:[startProcessing] from startProcessing::@6 [104] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) startProcessing::$28) ← (word) startProcessing::spriteX#0 [105] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) startProcessing::$28) ← (word) startProcessing::spriteY#0 [106] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 - [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c + [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 [109] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) startProcessing::$28) ← (byte) startProcessing::spritePtr#0 [110] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteCol#0 diff --git a/src/test/ref/complex/clearscreen/clearscreen.log b/src/test/ref/complex/clearscreen/clearscreen.log index d80285a28..f8a4a70e1 100644 --- a/src/test/ref/complex/clearscreen/clearscreen.log +++ b/src/test/ref/complex/clearscreen/clearscreen.log @@ -18,6 +18,9 @@ Fixing pointer array-indexing *((const struct ProcessingSprite*) PROCESSING + (b Fixing pointer array-indexing *((const struct ProcessingSprite*) PROCESSING + (byte) startProcessing::spriteIdx) Fixing pointer array-indexing *((const word*) VXSIN + (byte) processChars::xchar) Fixing pointer array-indexing *((const word*) VYSIN + (byte) processChars::ychar) +Constantified RValue *((const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← { x: (word) 0, y: (word) 0, vx: (word) 0, vy: (word) 0, id: (byte) 0, ptr: (byte) 0, col: (byte) 0, status: (const byte) STATUS_FREE, screenPtr: (byte*)(number) 0 } +Constantified RValue (struct ProcessingChar) getCharToProcess::closest ← (struct ProcessingChar){ (byte) getCharToProcess::x, (byte) getCharToProcess::y, (byte) getCharToProcess::dist } +Constantified RValue *((const struct ProcessingSprite*) PROCESSING + (byte~) startProcessing::$28) ← (struct ProcessingSprite){ (word) startProcessing::spriteX, (word) startProcessing::spriteY, (word~) startProcessing::$21, (word) $3c, (byte) startProcessing::spriteIdx, (byte) startProcessing::spritePtr, (byte) startProcessing::spriteCol, (const byte) STATUS_NEW, (byte*) startProcessing::screenPtr } Created struct value member variable (byte~) main::$5_x Created struct value member variable (byte~) main::$5_y Created struct value member variable (byte~) main::$5_dist @@ -39,15 +42,15 @@ Created struct value member variable (byte) startProcessing::center_y Created struct value member variable (byte) startProcessing::center_dist Converted struct value to member variables (struct ProcessingChar) startProcessing::center Converted procedure struct value parameter to member unwinding (void()) startProcessing((byte) startProcessing::center_x , (byte) startProcessing::center_y , (byte) startProcessing::center_dist) -Adding struct value list initializer *((word*~) main::$11 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((word*~) main::$12 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((word*~) main::$13 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((word*~) main::$14 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((byte*~) main::$15 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((byte*~) main::$16 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((byte*~) main::$17 + (byte~) main::$10) ← (number) 0 -Adding struct value list initializer *((byte*~) main::$18 + (byte~) main::$10) ← (const byte) STATUS_FREE -Adding struct value list initializer *((byte**~) main::$19 + (byte~) main::$10) ← (number) 0 +Adding struct value member variable copy *((word*~) main::$11 + (byte~) main::$10) ← (word) 0 +Adding struct value member variable copy *((word*~) main::$12 + (byte~) main::$10) ← (word) 0 +Adding struct value member variable copy *((word*~) main::$13 + (byte~) main::$10) ← (word) 0 +Adding struct value member variable copy *((word*~) main::$14 + (byte~) main::$10) ← (word) 0 +Adding struct value member variable copy *((byte*~) main::$15 + (byte~) main::$10) ← (byte) 0 +Adding struct value member variable copy *((byte*~) main::$16 + (byte~) main::$10) ← (byte) 0 +Adding struct value member variable copy *((byte*~) main::$17 + (byte~) main::$10) ← (byte) 0 +Adding struct value member variable copy *((byte*~) main::$18 + (byte~) main::$10) ← (const byte) STATUS_FREE +Adding struct value member variable copy *((byte**~) main::$19 + (byte~) main::$10) ← (byte*)(number) 0 Converted procedure call LValue to member unwinding { (byte~) main::$5_x, (byte~) main::$5_y, (byte~) main::$5_dist } ← call getCharToProcess Adding struct value member variable copy (byte) main::center_x ← (byte~) main::$5_x Adding struct value member variable copy (byte) main::center_y ← (byte~) main::$5_y @@ -56,9 +59,9 @@ Converted procedure struct value parameter to member unwinding in call (void~) m Adding struct value member variable copy (byte) getCharToProcess::closest_x ← (byte) 0 Adding struct value member variable copy (byte) getCharToProcess::closest_y ← (byte) 0 Adding struct value member variable copy (byte) getCharToProcess::closest_dist ← (const byte) NOT_FOUND -Adding struct value list initializer (byte) getCharToProcess::closest_x ← (byte) getCharToProcess::x -Adding struct value list initializer (byte) getCharToProcess::closest_y ← (byte) getCharToProcess::y -Adding struct value list initializer (byte) getCharToProcess::closest_dist ← (byte) getCharToProcess::dist +Adding struct value member variable copy (byte) getCharToProcess::closest_x ← (byte) getCharToProcess::x +Adding struct value member variable copy (byte) getCharToProcess::closest_y ← (byte) getCharToProcess::y +Adding struct value member variable copy (byte) getCharToProcess::closest_dist ← (byte) getCharToProcess::dist Adding struct value member variable copy (byte) getCharToProcess::return_x ← (byte) getCharToProcess::closest_x Adding struct value member variable copy (byte) getCharToProcess::return_y ← (byte) getCharToProcess::closest_y Adding struct value member variable copy (byte) getCharToProcess::return_dist ← (byte) getCharToProcess::closest_dist @@ -66,15 +69,15 @@ Adding struct value member variable copy (byte) getCharToProcess::return_x ← ( Adding struct value member variable copy (byte) getCharToProcess::return_y ← (byte) getCharToProcess::return_y Adding struct value member variable copy (byte) getCharToProcess::return_dist ← (byte) getCharToProcess::return_dist Converted procedure struct return value to member unwinding return { (byte) getCharToProcess::return_x, (byte) getCharToProcess::return_y, (byte) getCharToProcess::return_dist } -Adding struct value list initializer *((word*~) startProcessing::$29 + (byte~) startProcessing::$28) ← (word) startProcessing::spriteX -Adding struct value list initializer *((word*~) startProcessing::$30 + (byte~) startProcessing::$28) ← (word) startProcessing::spriteY -Adding struct value list initializer *((word*~) startProcessing::$31 + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 -Adding struct value list initializer *((word*~) startProcessing::$32 + (byte~) startProcessing::$28) ← (number) $3c -Adding struct value list initializer *((byte*~) startProcessing::$33 + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteIdx -Adding struct value list initializer *((byte*~) startProcessing::$34 + (byte~) startProcessing::$28) ← (byte) startProcessing::spritePtr -Adding struct value list initializer *((byte*~) startProcessing::$35 + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteCol -Adding struct value list initializer *((byte*~) startProcessing::$36 + (byte~) startProcessing::$28) ← (const byte) STATUS_NEW -Adding struct value list initializer *((byte**~) startProcessing::$37 + (byte~) startProcessing::$28) ← (byte*) startProcessing::screenPtr +Adding struct value member variable copy *((word*~) startProcessing::$29 + (byte~) startProcessing::$28) ← (word) startProcessing::spriteX +Adding struct value member variable copy *((word*~) startProcessing::$30 + (byte~) startProcessing::$28) ← (word) startProcessing::spriteY +Adding struct value member variable copy *((word*~) startProcessing::$31 + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 +Adding struct value member variable copy *((word*~) startProcessing::$32 + (byte~) startProcessing::$28) ← (word) $3c +Adding struct value member variable copy *((byte*~) startProcessing::$33 + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteIdx +Adding struct value member variable copy *((byte*~) startProcessing::$34 + (byte~) startProcessing::$28) ← (byte) startProcessing::spritePtr +Adding struct value member variable copy *((byte*~) startProcessing::$35 + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteCol +Adding struct value member variable copy *((byte*~) startProcessing::$36 + (byte~) startProcessing::$28) ← (const byte) STATUS_NEW +Adding struct value member variable copy *((byte**~) startProcessing::$37 + (byte~) startProcessing::$28) ← (byte*) startProcessing::screenPtr Replacing struct member reference (struct ProcessingChar) main::center.dist with member unwinding reference (byte) main::center_dist Replacing struct member reference (struct ProcessingChar) getCharToProcess::closest.dist with member unwinding reference (byte) getCharToProcess::closest_dist Replacing struct member reference (struct ProcessingChar) getCharToProcess::closest.dist with member unwinding reference (byte) getCharToProcess::closest_dist @@ -491,23 +494,23 @@ main::@7: scope:[main] from main::@3 main::@7 (byte) main::i#2 ← phi( main::@3/(byte) main::i#0 main::@7/(byte) main::i#1 ) (byte~) main::$10 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_PROCESSINGSPRITE (word*~) main::$11 ← (word*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_X - *((word*~) main::$11 + (byte~) main::$10) ← (number) 0 + *((word*~) main::$11 + (byte~) main::$10) ← (word) 0 (word*~) main::$12 ← (word*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y - *((word*~) main::$12 + (byte~) main::$10) ← (number) 0 + *((word*~) main::$12 + (byte~) main::$10) ← (word) 0 (word*~) main::$13 ← (word*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX - *((word*~) main::$13 + (byte~) main::$10) ← (number) 0 + *((word*~) main::$13 + (byte~) main::$10) ← (word) 0 (word*~) main::$14 ← (word*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY - *((word*~) main::$14 + (byte~) main::$10) ← (number) 0 + *((word*~) main::$14 + (byte~) main::$10) ← (word) 0 (byte*~) main::$15 ← (byte*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID - *((byte*~) main::$15 + (byte~) main::$10) ← (number) 0 + *((byte*~) main::$15 + (byte~) main::$10) ← (byte) 0 (byte*~) main::$16 ← (byte*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR - *((byte*~) main::$16 + (byte~) main::$10) ← (number) 0 + *((byte*~) main::$16 + (byte~) main::$10) ← (byte) 0 (byte*~) main::$17 ← (byte*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL - *((byte*~) main::$17 + (byte~) main::$10) ← (number) 0 + *((byte*~) main::$17 + (byte~) main::$10) ← (byte) 0 (byte*~) main::$18 ← (byte*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_STATUS *((byte*~) main::$18 + (byte~) main::$10) ← (const byte) STATUS_FREE (byte**~) main::$19 ← (byte**)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR - *((byte**~) main::$19 + (byte~) main::$10) ← ((byte*)) (number) 0 + *((byte**~) main::$19 + (byte~) main::$10) ← (byte*)(number) 0 (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,NUM_PROCESSING-1) (bool~) main::$4 ← (byte) main::i#1 != rangelast(0,NUM_PROCESSING-1) if((bool~) main::$4) goto main::@7 @@ -823,7 +826,7 @@ startProcessing::@10: scope:[startProcessing] from startProcessing::@9 (word*~) startProcessing::$31 ← (word*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX *((word*~) startProcessing::$31 + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 (word*~) startProcessing::$32 ← (word*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY - *((word*~) startProcessing::$32 + (byte~) startProcessing::$28) ← (number) $3c + *((word*~) startProcessing::$32 + (byte~) startProcessing::$28) ← (word) $3c (byte*~) startProcessing::$33 ← (byte*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID *((byte*~) startProcessing::$33 + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteIdx#1 (byte*~) startProcessing::$34 ← (byte*)(const struct ProcessingSprite*) PROCESSING + (const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR @@ -2212,13 +2215,6 @@ Adding number conversion cast (unumber) atan2_16::$12 in (number~) atan2_16::$12 Adding number conversion cast (unumber) $3e8 in (word) malloc::size#0 ← (number) $3e8 Adding number conversion cast (unumber) $3e8 in (word) malloc::size#1 ← (number) $3e8 Adding number conversion cast (unumber) $3e8 in (bool~) main::$3 ← (byte*) main::src#2 != (const byte*) SCREEN+(number) $3e8 -Adding number conversion cast (unumber) 0 in *((word*~) main::$11 + (byte~) main::$10) ← (number) 0 -Adding number conversion cast (unumber) 0 in *((word*~) main::$12 + (byte~) main::$10) ← (number) 0 -Adding number conversion cast (unumber) 0 in *((word*~) main::$13 + (byte~) main::$10) ← (number) 0 -Adding number conversion cast (unumber) 0 in *((word*~) main::$14 + (byte~) main::$10) ← (number) 0 -Adding number conversion cast (unumber) 0 in *((byte*~) main::$15 + (byte~) main::$10) ← (number) 0 -Adding number conversion cast (unumber) 0 in *((byte*~) main::$16 + (byte~) main::$10) ← (number) 0 -Adding number conversion cast (unumber) 0 in *((byte*~) main::$17 + (byte~) main::$10) ← (number) 0 Adding number conversion cast (unumber) 1 in (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,NUM_PROCESSING-1) Adding number conversion cast (unumber) $3e7 in *((const byte*) SCREEN+(number) $3e7) ← (byte) '.' Adding number conversion cast (unumber) $3e7 in *((const byte*) COLS+(number) $3e7) ← ++ *((const byte*) COLS+(number) $3e7) @@ -2249,7 +2245,6 @@ Adding number conversion cast (unumber) startProcessing::$18 in (number~) startP Adding number conversion cast (unumber) $40 in (byte~) startProcessing::$19 ← (byte)(const byte*) SPRITE_DATA/(number) $40 + (byte) startProcessing::spriteIdx#1 Adding number conversion cast (unumber) 8 in (number~) startProcessing::$20 ← (byte) startProcessing::spriteIdx#1 * (number) 8 Adding number conversion cast (unumber) startProcessing::$20 in (number~) startProcessing::$20 ← (byte) startProcessing::spriteIdx#1 * (unumber)(number) 8 -Adding number conversion cast (unumber) $3c in *((word*~) startProcessing::$32 + (byte~) startProcessing::$28) ← (number) $3c Adding number conversion cast (unumber) 1 in (number~) processChars::$2 ← (number) 1 << *((byte*~) processChars::$35) Adding number conversion cast (unumber) processChars::$2 in (number~) processChars::$2 ← (unumber)(number) 1 << *((byte*~) processChars::$35) Adding number conversion cast (unumber) 1 in (byte) processChars::i#1 ← (byte) processChars::i#3 + rangenext(0,NUM_PROCESSING-1) @@ -2308,14 +2303,6 @@ Inlining cast (word) malloc::size#0 ← (unumber)(number) $3e8 Inlining cast (byte*) SCREEN_COPY#0 ← (byte*)(void*~) $0 Inlining cast (word) malloc::size#1 ← (unumber)(number) $3e8 Inlining cast (byte*) SCREEN_DIST#0 ← (byte*)(void*~) $1 -Inlining cast *((word*~) main::$11 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((word*~) main::$12 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((word*~) main::$13 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((word*~) main::$14 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((byte*~) main::$15 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((byte*~) main::$16 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((byte*~) main::$17 + (byte~) main::$10) ← (unumber)(number) 0 -Inlining cast *((byte**~) main::$19 + (byte~) main::$10) ← (byte*)(number) 0 Inlining cast (word~) getCharToProcess::$8 ← (word)(byte) getCharToProcess::closest_y#3 Inlining cast (word~) startProcessing::$0 ← (word)(byte) startProcessing::center_y#1 Inlining cast (word~) startProcessing::$5 ← (word)(byte) startProcessing::spriteIdx#0 @@ -2323,7 +2310,6 @@ Inlining cast (word~) startProcessing::$8 ← (word)(byte) startProcessing::ch#0 Inlining cast (word~) startProcessing::$11 ← (word)(byte) startProcessing::center_x#2 Inlining cast (word~) startProcessing::$15 ← (word)(byte) startProcessing::center_y#2 Inlining cast (word~) startProcessing::$21 ← (word)(unumber~) startProcessing::$20 -Inlining cast *((word*~) startProcessing::$32 + (byte~) startProcessing::$28) ← (unumber)(number) $3c Inlining cast (byte~) processChars::$12 ← (byte)(word) processChars::xpos#1 Inlining cast (byte~) processChars::$14 ← (byte)(word~) processChars::$13 Inlining cast (byte~) processChars::$24 ← (byte)(unumber~) processChars::$23 @@ -2384,13 +2370,6 @@ Simplifying constant integer cast $8000 Simplifying constant integer cast $3e8 Simplifying constant integer cast $3e8 Simplifying constant integer cast $3e8 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 Simplifying constant pointer cast (byte*) 0 Simplifying constant integer cast 1 Simplifying constant integer cast $3e7 @@ -2410,7 +2389,6 @@ Simplifying constant integer cast 8 Simplifying constant integer cast 4 Simplifying constant integer cast $40 Simplifying constant integer cast 8 -Simplifying constant integer cast $3c Simplifying constant integer cast 1 Simplifying constant integer cast 1 Simplifying constant integer cast 4 @@ -2473,13 +2451,6 @@ Finalized unsigned number type (word) $8000 Finalized unsigned number type (word) $3e8 Finalized unsigned number type (word) $3e8 Finalized unsigned number type (word) $3e8 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 1 Finalized unsigned number type (word) $3e7 Finalized unsigned number type (word) $3e7 @@ -2498,7 +2469,6 @@ Finalized unsigned number type (byte) 8 Finalized unsigned number type (byte) 4 Finalized unsigned number type (byte) $40 Finalized unsigned number type (byte) 8 -Finalized unsigned number type (byte) $3c Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 4 @@ -3490,10 +3460,10 @@ main::@3: scope:[main] from main::@1 main::@3 [17] (byte~) main::$22 ← (byte~) main::$21 << (byte) 1 [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 - [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 - [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 - [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 - [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 + [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 + [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 + [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 + [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 @@ -3611,7 +3581,7 @@ startProcessing::@7: scope:[startProcessing] from startProcessing::@6 [104] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) startProcessing::$28) ← (word) startProcessing::spriteX#0 [105] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) startProcessing::$28) ← (word) startProcessing::spriteY#0 [106] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 - [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c + [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 [109] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) startProcessing::$28) ← (byte) startProcessing::spritePtr#0 [110] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteCol#0 @@ -4933,30 +4903,30 @@ main: { lda.z __23 asl sta.z __10 - // [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuz1=vbuc2 - lda.z __10 - ldx #0 - tay - txa + // [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuz1=vwuc2 + ldy.z __10 + lda #<0 sta PROCESSING,y - // [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuz1=vbuc2 - lda.z __10 - ldx #0 - tay - txa + lda #>0 + sta PROCESSING+1,y + // [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuz1=vwuc2 + ldy.z __10 + lda #<0 sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y,y - // [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuz1=vbuc2 - lda.z __10 - ldx #0 - tay - txa + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y+1,y + // [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuz1=vwuc2 + ldy.z __10 + lda #<0 sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,y - // [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuz1=vbuc2 - lda.z __10 - ldx #0 - tay - txa + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,y + // [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuz1=vwuc2 + ldy.z __10 + lda #<0 sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,y + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,y // [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuz1=vbuc2 lda #0 ldy.z __10 @@ -5493,12 +5463,12 @@ startProcessing: { sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,y lda.z __21+1 sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,y - // [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c -- pwuc1_derefidx_vbuz1=vbuc2 - lda.z __28 - ldx #$3c - tay - txa + // [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c -- pwuc1_derefidx_vbuz1=vwuc2 + ldy.z __28 + lda #<$3c sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,y + lda #>$3c + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,y // [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 -- pbuc1_derefidx_vbuz1=vbuz2 lda.z freeIdx ldy.z __28 @@ -6984,11 +6954,11 @@ Statement [16] (byte~) main::$21 ← (byte~) main::$20 + (byte) main::i#2 [ SCRE Statement [17] (byte~) main::$22 ← (byte~) main::$21 << (byte) 1 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$22 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$22 ] ) always clobbers reg byte a Statement [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$23 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$23 ] ) always clobbers reg byte a Statement [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:62 [ main::$10 ] -Statement [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Statement [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Statement [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Statement [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a @@ -7053,7 +7023,7 @@ Statement [104] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) s Removing always clobbered register reg byte a as potential for zp[1]:124 [ startProcessing::$28 ] Statement [105] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) startProcessing::$28) ← (word) startProcessing::spriteY#0 [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$21 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$21 startProcessing::$28 ] ) always clobbers reg byte a Statement [106] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a -Statement [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a +Statement [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a Statement [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 [ startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a Statement [109] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) startProcessing::$28) ← (byte) startProcessing::spritePtr#0 [ startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::$28 ] ) always clobbers reg byte a Statement [110] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteCol#0 [ startProcessing::screenPtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::screenPtr#0 startProcessing::$28 ] ) always clobbers reg byte a @@ -7223,10 +7193,10 @@ Statement [16] (byte~) main::$21 ← (byte~) main::$20 + (byte) main::i#2 [ SCRE Statement [17] (byte~) main::$22 ← (byte~) main::$21 << (byte) 1 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$22 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$22 ] ) always clobbers reg byte a Statement [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$23 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$23 ] ) always clobbers reg byte a Statement [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a -Statement [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a +Statement [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Statement [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Statement [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a Statement [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ( main:7 [ SCREEN_COPY#0 SCREEN_DIST#0 main::i#2 main::$10 ] ) always clobbers reg byte a @@ -7278,7 +7248,7 @@ Statement [103] (byte~) startProcessing::$28 ← (byte~) startProcessing::$50 << Statement [104] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) startProcessing::$28) ← (word) startProcessing::spriteX#0 [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spriteY#0 startProcessing::spritePtr#0 startProcessing::$21 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spriteY#0 startProcessing::spritePtr#0 startProcessing::$21 startProcessing::$28 ] ) always clobbers reg byte a Statement [105] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) startProcessing::$28) ← (word) startProcessing::spriteY#0 [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$21 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$21 startProcessing::$28 ] ) always clobbers reg byte a Statement [106] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) startProcessing::$28) ← (word~) startProcessing::$21 [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a -Statement [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a +Statement [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c [ startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::freeIdx#2 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a Statement [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 [ startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::spritePtr#0 startProcessing::$28 ] ) always clobbers reg byte a Statement [109] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) startProcessing::$28) ← (byte) startProcessing::spritePtr#0 [ startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::spriteCol#0 startProcessing::screenPtr#0 startProcessing::$28 ] ) always clobbers reg byte a Statement [110] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) startProcessing::$28) ← (byte) startProcessing::spriteCol#0 [ startProcessing::screenPtr#0 startProcessing::$28 ] ( main:7::startProcessing:48 [ SCREEN_COPY#0 SCREEN_DIST#0 startProcessing::screenPtr#0 startProcessing::$28 ] ) always clobbers reg byte a @@ -7556,142 +7526,142 @@ Uplift Scope [setupRasterIrq] Uplift Scope [irqTop] Uplift Scope [irqBottom] -Uplifting [atan2_16] best 1280009 combination reg byte y [ atan2_16::shift#2 atan2_16::shift#5 atan2_16::shift#1 ] zp[2]:44 [ atan2_16::yd#5 atan2_16::yd#3 atan2_16::yd#10 atan2_16::yd#1 atan2_16::yd#2 ] zp[2]:46 [ atan2_16::xd#5 atan2_16::xd#3 atan2_16::xd#10 atan2_16::xd#1 atan2_16::xd#2 ] zp[2]:39 [ atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 ] zp[2]:34 [ atan2_16::yi#3 atan2_16::yi#8 atan2_16::yi#0 atan2_16::yi#16 atan2_16::$2 atan2_16::yi#1 atan2_16::yi#2 ] zp[2]:36 [ atan2_16::xi#3 atan2_16::xi#8 atan2_16::xi#0 atan2_16::xi#13 atan2_16::$7 atan2_16::xi#1 atan2_16::xi#2 ] reg byte a [ atan2_16::$23 ] reg byte a [ atan2_16::$22 ] reg byte x [ atan2_16::i#2 atan2_16::i#1 ] zp[2]:146 [ atan2_16::return#2 ] zp[2]:41 [ atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 ] zp[2]:142 [ atan2_16::x#0 ] zp[2]:144 [ atan2_16::y#0 ] +Uplifting [atan2_16] best 1280132 combination reg byte y [ atan2_16::shift#2 atan2_16::shift#5 atan2_16::shift#1 ] zp[2]:44 [ atan2_16::yd#5 atan2_16::yd#3 atan2_16::yd#10 atan2_16::yd#1 atan2_16::yd#2 ] zp[2]:46 [ atan2_16::xd#5 atan2_16::xd#3 atan2_16::xd#10 atan2_16::xd#1 atan2_16::xd#2 ] zp[2]:39 [ atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 ] zp[2]:34 [ atan2_16::yi#3 atan2_16::yi#8 atan2_16::yi#0 atan2_16::yi#16 atan2_16::$2 atan2_16::yi#1 atan2_16::yi#2 ] zp[2]:36 [ atan2_16::xi#3 atan2_16::xi#8 atan2_16::xi#0 atan2_16::xi#13 atan2_16::$7 atan2_16::xi#1 atan2_16::xi#2 ] reg byte a [ atan2_16::$23 ] reg byte a [ atan2_16::$22 ] reg byte x [ atan2_16::i#2 atan2_16::i#1 ] zp[2]:146 [ atan2_16::return#2 ] zp[2]:41 [ atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 ] zp[2]:142 [ atan2_16::x#0 ] zp[2]:144 [ atan2_16::y#0 ] Limited combination testing to 100 combinations of 144 possible. -Uplifting [getCharToProcess] best 1266676 combination reg byte x [ getCharToProcess::return_dist#1 getCharToProcess::return_dist#5 getCharToProcess::return_dist#6 getCharToProcess::dist#0 ] zp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] zp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] zp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] zp[1]:19 [ getCharToProcess::x#2 getCharToProcess::x#1 ] zp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] zp[2]:16 [ getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 ] zp[2]:14 [ getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 ] zp[1]:63 [ getCharToProcess::return_x#0 ] zp[1]:64 [ getCharToProcess::return_y#0 ] zp[1]:65 [ getCharToProcess::return_dist#0 ] zp[2]:127 [ getCharToProcess::$12 ] zp[2]:129 [ getCharToProcess::$13 ] zp[2]:131 [ getCharToProcess::$9 ] zp[2]:133 [ getCharToProcess::$10 ] zp[2]:125 [ getCharToProcess::$8 ] +Uplifting [getCharToProcess] best 1266799 combination reg byte x [ getCharToProcess::return_dist#1 getCharToProcess::return_dist#5 getCharToProcess::return_dist#6 getCharToProcess::dist#0 ] zp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] zp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] zp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] zp[1]:19 [ getCharToProcess::x#2 getCharToProcess::x#1 ] zp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] zp[2]:16 [ getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 ] zp[2]:14 [ getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 ] zp[1]:63 [ getCharToProcess::return_x#0 ] zp[1]:64 [ getCharToProcess::return_y#0 ] zp[1]:65 [ getCharToProcess::return_dist#0 ] zp[2]:127 [ getCharToProcess::$12 ] zp[2]:129 [ getCharToProcess::$13 ] zp[2]:131 [ getCharToProcess::$9 ] zp[2]:133 [ getCharToProcess::$10 ] zp[2]:125 [ getCharToProcess::$8 ] Limited combination testing to 100 combinations of 46656 possible. -Uplifting [init_angle_screen] best 1265076 combination zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] reg byte a [ init_angle_screen::$3 ] reg byte a [ init_angle_screen::$4 ] reg byte a [ init_angle_screen::$7 ] zp[2]:148 [ init_angle_screen::angle_w#0 ] zp[2]:150 [ init_angle_screen::$11 ] zp[1]:153 [ init_angle_screen::$13 ] zp[1]:154 [ init_angle_screen::$14 ] zp[1]:155 [ init_angle_screen::$15 ] zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] zp[1]:152 [ init_angle_screen::ang_w#0 ] zp[2]:140 [ init_angle_screen::yw#0 ] zp[2]:137 [ init_angle_screen::xw#0 ] zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] zp[2]:30 [ init_angle_screen::screen_bottomline#6 init_angle_screen::screen_bottomline#0 init_angle_screen::screen_bottomline#1 ] zp[2]:28 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 ] zp[2]:56 [ init_angle_screen::screen#0 ] +Uplifting [init_angle_screen] best 1265199 combination zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] reg byte a [ init_angle_screen::$3 ] reg byte a [ init_angle_screen::$4 ] reg byte a [ init_angle_screen::$7 ] zp[2]:148 [ init_angle_screen::angle_w#0 ] zp[2]:150 [ init_angle_screen::$11 ] zp[1]:153 [ init_angle_screen::$13 ] zp[1]:154 [ init_angle_screen::$14 ] zp[1]:155 [ init_angle_screen::$15 ] zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] zp[1]:152 [ init_angle_screen::ang_w#0 ] zp[2]:140 [ init_angle_screen::yw#0 ] zp[2]:137 [ init_angle_screen::xw#0 ] zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] zp[2]:30 [ init_angle_screen::screen_bottomline#6 init_angle_screen::screen_bottomline#0 init_angle_screen::screen_bottomline#1 ] zp[2]:28 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 ] zp[2]:56 [ init_angle_screen::screen#0 ] Limited combination testing to 100 combinations of 65536 possible. -Uplifting [main] best 1264836 combination zp[2]:4 [ main::dst#2 main::dst#0 main::dst#1 ] zp[2]:2 [ main::src#2 main::src#1 ] reg byte a [ main::$20 ] reg byte a [ main::$21 ] reg byte a [ main::$22 ] reg byte a [ main::$23 ] zp[1]:68 [ main::center_dist#0 ] zp[1]:6 [ main::i#2 main::i#1 ] zp[1]:62 [ main::$10 ] zp[1]:66 [ main::center_x#0 ] zp[1]:67 [ main::center_y#0 ] +Uplifting [main] best 1264959 combination zp[2]:4 [ main::dst#2 main::dst#0 main::dst#1 ] zp[2]:2 [ main::src#2 main::src#1 ] reg byte a [ main::$20 ] reg byte a [ main::$21 ] reg byte a [ main::$22 ] reg byte a [ main::$23 ] zp[1]:68 [ main::center_dist#0 ] zp[1]:6 [ main::i#2 main::i#1 ] zp[1]:62 [ main::$10 ] zp[1]:66 [ main::center_x#0 ] zp[1]:67 [ main::center_y#0 ] Limited combination testing to 100 combinations of 147456 possible. -Uplifting [initSprites] best 1264716 combination zp[2]:24 [ initSprites::sp#2 initSprites::sp#1 ] reg byte x [ initSprites::i#2 initSprites::i#1 ] -Uplifting [] best 1264716 combination zp[2]:48 [ heap_head#5 heap_head#1 ] zp[2]:54 [ SCREEN_DIST#0 ] zp[2]:52 [ SCREEN_COPY#0 ] -Uplifting [malloc] best 1264716 combination zp[2]:158 [ malloc::mem#0 ] -Uplifting [RADIX] best 1264716 combination -Uplifting [ProcessingChar] best 1264716 combination -Uplifting [ProcessingSprite] best 1264716 combination -Uplifting [ProcessingSprite::$0] best 1264716 combination -Uplifting [setupRasterIrq] best 1264716 combination -Uplifting [irqTop] best 1264716 combination -Uplifting [irqBottom] best 1264716 combination +Uplifting [initSprites] best 1264839 combination zp[2]:24 [ initSprites::sp#2 initSprites::sp#1 ] reg byte x [ initSprites::i#2 initSprites::i#1 ] +Uplifting [] best 1264839 combination zp[2]:48 [ heap_head#5 heap_head#1 ] zp[2]:54 [ SCREEN_DIST#0 ] zp[2]:52 [ SCREEN_COPY#0 ] +Uplifting [malloc] best 1264839 combination zp[2]:158 [ malloc::mem#0 ] +Uplifting [RADIX] best 1264839 combination +Uplifting [ProcessingChar] best 1264839 combination +Uplifting [ProcessingSprite] best 1264839 combination +Uplifting [ProcessingSprite::$0] best 1264839 combination +Uplifting [setupRasterIrq] best 1264839 combination +Uplifting [irqTop] best 1264839 combination +Uplifting [irqBottom] best 1264839 combination Attempting to uplift remaining variables inzp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] -Uplifting [getCharToProcess] best 1264716 combination zp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] +Uplifting [getCharToProcess] best 1264839 combination zp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] Attempting to uplift remaining variables inzp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] -Uplifting [getCharToProcess] best 1264716 combination zp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] +Uplifting [getCharToProcess] best 1264839 combination zp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] Attempting to uplift remaining variables inzp[1]:8 [ startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] -Uplifting [startProcessing] best 1264716 combination zp[1]:8 [ startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] +Uplifting [startProcessing] best 1264839 combination zp[1]:8 [ startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] Attempting to uplift remaining variables inzp[1]:71 [ startProcessing::$39 ] -Uplifting [startProcessing] best 1258716 combination reg byte a [ startProcessing::$39 ] +Uplifting [startProcessing] best 1258839 combination reg byte a [ startProcessing::$39 ] Attempting to uplift remaining variables inzp[1]:72 [ startProcessing::$40 ] -Uplifting [startProcessing] best 1252716 combination reg byte a [ startProcessing::$40 ] +Uplifting [startProcessing] best 1252839 combination reg byte a [ startProcessing::$40 ] Attempting to uplift remaining variables inzp[1]:73 [ startProcessing::$41 ] -Uplifting [startProcessing] best 1246716 combination reg byte a [ startProcessing::$41 ] +Uplifting [startProcessing] best 1246839 combination reg byte a [ startProcessing::$41 ] Attempting to uplift remaining variables inzp[1]:74 [ startProcessing::$42 ] -Uplifting [startProcessing] best 1240716 combination reg byte a [ startProcessing::$42 ] +Uplifting [startProcessing] best 1240839 combination reg byte a [ startProcessing::$42 ] Attempting to uplift remaining variables inzp[1]:75 [ startProcessing::$27 ] -Uplifting [startProcessing] best 1236716 combination reg byte a [ startProcessing::$27 ] +Uplifting [startProcessing] best 1236839 combination reg byte a [ startProcessing::$27 ] Attempting to uplift remaining variables inzp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] -Uplifting [getCharToProcess] best 1236716 combination zp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] +Uplifting [getCharToProcess] best 1236839 combination zp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] Attempting to uplift remaining variables inzp[1]:19 [ getCharToProcess::x#2 getCharToProcess::x#1 ] -Uplifting [getCharToProcess] best 1218716 combination reg byte y [ getCharToProcess::x#2 getCharToProcess::x#1 ] +Uplifting [getCharToProcess] best 1218839 combination reg byte y [ getCharToProcess::x#2 getCharToProcess::x#1 ] Attempting to uplift remaining variables inzp[1]:7 [ startProcessing::freeIdx#6 startProcessing::freeIdx#7 ] -Uplifting [startProcessing] best 1217816 combination reg byte x [ startProcessing::freeIdx#6 startProcessing::freeIdx#7 ] +Uplifting [startProcessing] best 1217939 combination reg byte x [ startProcessing::freeIdx#6 startProcessing::freeIdx#7 ] Attempting to uplift remaining variables inzp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] -Uplifting [init_angle_screen] best 1217816 combination zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] +Uplifting [init_angle_screen] best 1217939 combination zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] Attempting to uplift remaining variables inzp[1]:13 [ startProcessing::i1#2 startProcessing::i1#1 ] -Uplifting [startProcessing] best 1216916 combination reg byte x [ startProcessing::i1#2 startProcessing::i1#1 ] +Uplifting [startProcessing] best 1217039 combination reg byte x [ startProcessing::i1#2 startProcessing::i1#1 ] Attempting to uplift remaining variables inzp[1]:153 [ init_angle_screen::$13 ] -Uplifting [init_angle_screen] best 1216316 combination reg byte a [ init_angle_screen::$13 ] +Uplifting [init_angle_screen] best 1216439 combination reg byte a [ init_angle_screen::$13 ] Attempting to uplift remaining variables inzp[1]:154 [ init_angle_screen::$14 ] -Uplifting [init_angle_screen] best 1215916 combination reg byte a [ init_angle_screen::$14 ] +Uplifting [init_angle_screen] best 1216039 combination reg byte a [ init_angle_screen::$14 ] Attempting to uplift remaining variables inzp[1]:155 [ init_angle_screen::$15 ] -Uplifting [init_angle_screen] best 1215316 combination reg byte a [ init_angle_screen::$15 ] +Uplifting [init_angle_screen] best 1215439 combination reg byte a [ init_angle_screen::$15 ] Attempting to uplift remaining variables inzp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] -Uplifting [getCharToProcess] best 1215316 combination zp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] +Uplifting [getCharToProcess] best 1215439 combination zp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] Attempting to uplift remaining variables inzp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] -Uplifting [init_angle_screen] best 1215316 combination zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] +Uplifting [init_angle_screen] best 1215439 combination zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] Attempting to uplift remaining variables inzp[1]:152 [ init_angle_screen::ang_w#0 ] -Uplifting [init_angle_screen] best 1215316 combination zp[1]:152 [ init_angle_screen::ang_w#0 ] +Uplifting [init_angle_screen] best 1215439 combination zp[1]:152 [ init_angle_screen::ang_w#0 ] Attempting to uplift remaining variables inzp[1]:51 [ processChars::numActive#10 processChars::numActive#3 processChars::numActive#1 ] -Uplifting [processChars] best 1215316 combination zp[1]:51 [ processChars::numActive#10 processChars::numActive#3 processChars::numActive#1 ] +Uplifting [processChars] best 1215439 combination zp[1]:51 [ processChars::numActive#10 processChars::numActive#3 processChars::numActive#1 ] Attempting to uplift remaining variables inzp[1]:68 [ main::center_dist#0 ] -Uplifting [main] best 1215256 combination reg byte a [ main::center_dist#0 ] +Uplifting [main] best 1215379 combination reg byte a [ main::center_dist#0 ] Attempting to uplift remaining variables inzp[1]:160 [ processChars::$62 ] -Uplifting [processChars] best 1215196 combination reg byte a [ processChars::$62 ] +Uplifting [processChars] best 1215319 combination reg byte a [ processChars::$62 ] Attempting to uplift remaining variables inzp[1]:161 [ processChars::$63 ] -Uplifting [processChars] best 1215136 combination reg byte a [ processChars::$63 ] +Uplifting [processChars] best 1215259 combination reg byte a [ processChars::$63 ] Attempting to uplift remaining variables inzp[1]:162 [ processChars::$64 ] -Uplifting [processChars] best 1215076 combination reg byte a [ processChars::$64 ] +Uplifting [processChars] best 1215199 combination reg byte a [ processChars::$64 ] Attempting to uplift remaining variables inzp[1]:163 [ processChars::$65 ] -Uplifting [processChars] best 1215016 combination reg byte a [ processChars::$65 ] +Uplifting [processChars] best 1215139 combination reg byte a [ processChars::$65 ] Attempting to uplift remaining variables inzp[1]:164 [ processChars::$32 ] -Uplifting [processChars] best 1214956 combination reg byte a [ processChars::$32 ] +Uplifting [processChars] best 1215079 combination reg byte a [ processChars::$32 ] Attempting to uplift remaining variables inzp[1]:170 [ processChars::$9 ] -Uplifting [processChars] best 1214896 combination reg byte a [ processChars::$9 ] +Uplifting [processChars] best 1215019 combination reg byte a [ processChars::$9 ] Attempting to uplift remaining variables inzp[1]:171 [ processChars::$10 ] -Uplifting [processChars] best 1214836 combination reg byte a [ processChars::$10 ] +Uplifting [processChars] best 1214959 combination reg byte a [ processChars::$10 ] Attempting to uplift remaining variables inzp[1]:173 [ processChars::$12 ] -Uplifting [processChars] best 1214776 combination reg byte a [ processChars::$12 ] +Uplifting [processChars] best 1214899 combination reg byte a [ processChars::$12 ] Attempting to uplift remaining variables inzp[1]:179 [ processChars::$24 ] -Uplifting [processChars] best 1214736 combination reg byte a [ processChars::$24 ] +Uplifting [processChars] best 1214859 combination reg byte a [ processChars::$24 ] Attempting to uplift remaining variables inzp[1]:180 [ processChars::xchar#0 ] -Uplifting [processChars] best 1214676 combination reg byte a [ processChars::xchar#0 ] +Uplifting [processChars] best 1214799 combination reg byte a [ processChars::xchar#0 ] Attempting to uplift remaining variables inzp[1]:181 [ processChars::$33 ] -Uplifting [processChars] best 1214636 combination reg byte a [ processChars::$33 ] +Uplifting [processChars] best 1214759 combination reg byte a [ processChars::$33 ] Attempting to uplift remaining variables inzp[1]:182 [ processChars::$27 ] -Uplifting [processChars] best 1214596 combination reg byte a [ processChars::$27 ] +Uplifting [processChars] best 1214719 combination reg byte a [ processChars::$27 ] Attempting to uplift remaining variables inzp[1]:183 [ processChars::ychar#0 ] -Uplifting [processChars] best 1214536 combination reg byte a [ processChars::ychar#0 ] +Uplifting [processChars] best 1214659 combination reg byte a [ processChars::ychar#0 ] Attempting to uplift remaining variables inzp[1]:184 [ processChars::$34 ] -Uplifting [processChars] best 1214496 combination reg byte a [ processChars::$34 ] +Uplifting [processChars] best 1214619 combination reg byte a [ processChars::$34 ] Attempting to uplift remaining variables inzp[1]:185 [ processChars::$29 ] -Uplifting [processChars] best 1214436 combination reg byte a [ processChars::$29 ] +Uplifting [processChars] best 1214559 combination reg byte a [ processChars::$29 ] Attempting to uplift remaining variables inzp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] -Uplifting [init_angle_screen] best 1214436 combination zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] +Uplifting [init_angle_screen] best 1214559 combination zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] Attempting to uplift remaining variables inzp[1]:6 [ main::i#2 main::i#1 ] -Uplifting [main] best 1214436 combination zp[1]:6 [ main::i#2 main::i#1 ] +Uplifting [main] best 1214519 combination reg byte x [ main::i#2 main::i#1 ] Attempting to uplift remaining variables inzp[1]:50 [ processChars::i#10 processChars::i#1 ] -Uplifting [processChars] best 1214436 combination zp[1]:50 [ processChars::i#10 processChars::i#1 ] +Uplifting [processChars] best 1214519 combination zp[1]:50 [ processChars::i#10 processChars::i#1 ] Attempting to uplift remaining variables inzp[1]:62 [ main::$10 ] -Uplifting [main] best 1214276 combination reg byte x [ main::$10 ] +Uplifting [main] best 1214239 combination reg byte y [ main::$10 ] Attempting to uplift remaining variables inzp[1]:63 [ getCharToProcess::return_x#0 ] -Uplifting [getCharToProcess] best 1214216 combination reg byte y [ getCharToProcess::return_x#0 ] +Uplifting [getCharToProcess] best 1214179 combination reg byte y [ getCharToProcess::return_x#0 ] Attempting to uplift remaining variables inzp[1]:64 [ getCharToProcess::return_y#0 ] -Uplifting [getCharToProcess] best 1214156 combination reg byte a [ getCharToProcess::return_y#0 ] +Uplifting [getCharToProcess] best 1214119 combination reg byte a [ getCharToProcess::return_y#0 ] Attempting to uplift remaining variables inzp[1]:65 [ getCharToProcess::return_dist#0 ] -Uplifting [getCharToProcess] best 1214116 combination reg byte x [ getCharToProcess::return_dist#0 ] +Uplifting [getCharToProcess] best 1214079 combination reg byte x [ getCharToProcess::return_dist#0 ] Attempting to uplift remaining variables inzp[1]:172 [ processChars::$15 ] -Uplifting [processChars] best 1214046 combination reg byte x [ processChars::$15 ] +Uplifting [processChars] best 1214009 combination reg byte x [ processChars::$15 ] Attempting to uplift remaining variables inzp[1]:66 [ main::center_x#0 ] -Uplifting [main] best 1213986 combination reg byte y [ main::center_x#0 ] +Uplifting [main] best 1213949 combination reg byte y [ main::center_x#0 ] Attempting to uplift remaining variables inzp[1]:67 [ main::center_y#0 ] -Uplifting [main] best 1213986 combination zp[1]:67 [ main::center_y#0 ] +Uplifting [main] best 1213949 combination zp[1]:67 [ main::center_y#0 ] Attempting to uplift remaining variables inzp[1]:120 [ startProcessing::$47 ] -Uplifting [startProcessing] best 1213980 combination reg byte a [ startProcessing::$47 ] +Uplifting [startProcessing] best 1213943 combination reg byte a [ startProcessing::$47 ] Attempting to uplift remaining variables inzp[1]:121 [ startProcessing::$48 ] -Uplifting [startProcessing] best 1213974 combination reg byte a [ startProcessing::$48 ] +Uplifting [startProcessing] best 1213937 combination reg byte a [ startProcessing::$48 ] Attempting to uplift remaining variables inzp[1]:122 [ startProcessing::$49 ] -Uplifting [startProcessing] best 1213968 combination reg byte a [ startProcessing::$49 ] +Uplifting [startProcessing] best 1213931 combination reg byte a [ startProcessing::$49 ] Attempting to uplift remaining variables inzp[1]:123 [ startProcessing::$50 ] -Uplifting [startProcessing] best 1213962 combination reg byte a [ startProcessing::$50 ] +Uplifting [startProcessing] best 1213925 combination reg byte a [ startProcessing::$50 ] Attempting to uplift remaining variables inzp[1]:176 [ processChars::ypos#0 ] -Uplifting [processChars] best 1213962 combination zp[1]:176 [ processChars::ypos#0 ] +Uplifting [processChars] best 1213925 combination zp[1]:176 [ processChars::ypos#0 ] Attempting to uplift remaining variables inzp[1]:124 [ startProcessing::$28 ] -Uplifting [startProcessing] best 1213937 combination reg byte x [ startProcessing::$28 ] +Uplifting [startProcessing] best 1213897 combination reg byte x [ startProcessing::$28 ] Attempting to uplift remaining variables inzp[1]:167 [ processChars::bitmask#0 ] -Uplifting [processChars] best 1213937 combination zp[1]:167 [ processChars::bitmask#0 ] +Uplifting [processChars] best 1213897 combination zp[1]:167 [ processChars::bitmask#0 ] Attempting to uplift remaining variables inzp[1]:95 [ startProcessing::ch#0 ] -Uplifting [startProcessing] best 1213931 combination reg byte a [ startProcessing::ch#0 ] +Uplifting [startProcessing] best 1213891 combination reg byte a [ startProcessing::ch#0 ] Attempting to uplift remaining variables inzp[1]:117 [ startProcessing::$20 ] -Uplifting [startProcessing] best 1213925 combination reg byte a [ startProcessing::$20 ] +Uplifting [startProcessing] best 1213885 combination reg byte a [ startProcessing::$20 ] Attempting to uplift remaining variables inzp[1]:69 [ startProcessing::center_x#0 ] -Uplifting [startProcessing] best 1213925 combination zp[1]:69 [ startProcessing::center_x#0 ] +Uplifting [startProcessing] best 1213885 combination zp[1]:69 [ startProcessing::center_x#0 ] Attempting to uplift remaining variables inzp[1]:116 [ startProcessing::spritePtr#0 ] -Uplifting [startProcessing] best 1213925 combination zp[1]:116 [ startProcessing::spritePtr#0 ] +Uplifting [startProcessing] best 1213885 combination zp[1]:116 [ startProcessing::spritePtr#0 ] Attempting to uplift remaining variables inzp[1]:70 [ startProcessing::center_y#0 ] -Uplifting [startProcessing] best 1213925 combination zp[1]:70 [ startProcessing::center_y#0 ] +Uplifting [startProcessing] best 1213885 combination zp[1]:70 [ startProcessing::center_y#0 ] Attempting to uplift remaining variables inzp[1]:88 [ startProcessing::spriteCol#0 ] -Uplifting [startProcessing] best 1213925 combination zp[1]:88 [ startProcessing::spriteCol#0 ] +Uplifting [startProcessing] best 1213885 combination zp[1]:88 [ startProcessing::spriteCol#0 ] Coalescing zero page register [ zp[2]:9 [ startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 ] ] with [ zp[2]:98 [ startProcessing::$9 ] ] - score: 1 Coalescing zero page register [ zp[2]:11 [ startProcessing::spriteData#2 startProcessing::spriteData#0 startProcessing::spriteData#1 ] ] with [ zp[2]:93 [ startProcessing::$6 ] ] - score: 1 Coalescing zero page register [ zp[2]:30 [ init_angle_screen::screen_bottomline#6 init_angle_screen::screen_bottomline#0 init_angle_screen::screen_bottomline#1 ] ] with [ zp[2]:56 [ init_angle_screen::screen#0 ] ] - score: 1 @@ -7719,16 +7689,15 @@ Coalescing zero page register [ zp[2]:108 [ startProcessing::$15 startProcessing Coalescing zero page register [ zp[2]:125 [ getCharToProcess::$8 getCharToProcess::$13 ] ] with [ zp[2]:131 [ getCharToProcess::$9 getCharToProcess::$10 ] ] - score: 1 Coalescing zero page register [ zp[2]:39 [ atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 atan2_16::return#2 init_angle_screen::angle_w#0 ] ] with [ zp[2]:150 [ init_angle_screen::$11 ] ] - score: 1 Coalescing zero page register [ zp[2]:76 [ startProcessing::$0 startProcessing::$45 startProcessing::$1 startProcessing::offset#0 ] ] with [ zp[2]:89 [ startProcessing::screenPtr#0 ] ] - score: 1 -Coalescing zero page register [ zp[1]:8 [ startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] ] with [ zp[1]:6 [ main::i#2 main::i#1 ] ] Coalescing zero page register [ zp[2]:9 [ startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 startProcessing::$9 startProcessing::$8 ] ] with [ zp[2]:2 [ main::src#2 main::src#1 ] ] Coalescing zero page register [ zp[2]:11 [ startProcessing::spriteData#2 startProcessing::spriteData#0 startProcessing::spriteData#1 startProcessing::$6 startProcessing::$5 ] ] with [ zp[2]:4 [ main::dst#2 main::dst#0 main::dst#1 ] ] +Coalescing zero page register [ zp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] ] with [ zp[1]:8 [ startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] ] Coalescing zero page register [ zp[2]:24 [ initSprites::sp#2 initSprites::sp#1 ] ] with [ zp[2]:14 [ getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 ] ] -Coalescing zero page register [ zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] ] with [ zp[1]:18 [ getCharToProcess::y#7 getCharToProcess::y#1 ] ] +Coalescing zero page register [ zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 ] ] with [ zp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] ] Coalescing zero page register [ zp[2]:28 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 ] ] with [ zp[2]:16 [ getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 ] ] -Coalescing zero page register [ zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] ] with [ zp[1]:20 [ getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] ] -Coalescing zero page register [ zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] ] with [ zp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] ] +Coalescing zero page register [ zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 ] ] with [ zp[1]:21 [ getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] ] +Coalescing zero page register [ zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 ] ] with [ zp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] ] Coalescing zero page register [ zp[2]:48 [ heap_head#5 heap_head#1 ] ] with [ zp[2]:30 [ init_angle_screen::screen_bottomline#6 init_angle_screen::screen_bottomline#0 init_angle_screen::screen_bottomline#1 init_angle_screen::screen#0 ] ] -Coalescing zero page register [ zp[1]:67 [ main::center_y#0 startProcessing::center_y#0 ] ] with [ zp[1]:22 [ getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] ] Coalescing zero page register [ zp[2]:76 [ startProcessing::$0 startProcessing::$45 startProcessing::$1 startProcessing::offset#0 startProcessing::screenPtr#0 ] ] with [ zp[2]:34 [ atan2_16::yi#3 atan2_16::yi#8 atan2_16::yi#0 atan2_16::yi#16 atan2_16::$2 atan2_16::yi#1 atan2_16::yi#2 ] ] Coalescing zero page register [ zp[2]:78 [ startProcessing::$44 ] ] with [ zp[2]:36 [ atan2_16::xi#3 atan2_16::xi#8 atan2_16::xi#0 atan2_16::xi#13 atan2_16::$7 atan2_16::xi#1 atan2_16::xi#2 ] ] Coalescing zero page register [ zp[2]:86 [ startProcessing::colPtr#0 ] ] with [ zp[2]:39 [ atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 atan2_16::return#2 init_angle_screen::angle_w#0 init_angle_screen::$11 ] ] @@ -7736,32 +7705,32 @@ Coalescing zero page register [ zp[2]:100 [ startProcessing::$11 startProcessing Coalescing zero page register [ zp[2]:108 [ startProcessing::$15 startProcessing::$16 startProcessing::$17 startProcessing::spriteY#0 ] ] with [ zp[2]:46 [ atan2_16::xd#5 atan2_16::xd#3 atan2_16::xd#10 atan2_16::xd#1 atan2_16::xd#2 ] ] Coalescing zero page register [ zp[2]:125 [ getCharToProcess::$8 getCharToProcess::$13 getCharToProcess::$9 getCharToProcess::$10 ] ] with [ zp[2]:118 [ startProcessing::$21 ] ] Coalescing zero page register [ zp[2]:137 [ init_angle_screen::xw#0 atan2_16::x#0 ] ] with [ zp[2]:127 [ getCharToProcess::$12 ] ] -Coalescing zero page register [ zp[1]:152 [ init_angle_screen::ang_w#0 ] ] with [ zp[1]:69 [ startProcessing::center_x#0 ] ] +Coalescing zero page register [ zp[1]:152 [ init_angle_screen::ang_w#0 ] ] with [ zp[1]:67 [ main::center_y#0 startProcessing::center_y#0 ] ] Coalescing zero page register [ zp[2]:24 [ initSprites::sp#2 initSprites::sp#1 getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 ] ] with [ zp[2]:9 [ startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 startProcessing::$9 startProcessing::$8 main::src#2 main::src#1 ] ] -Coalescing zero page register [ zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::y#7 getCharToProcess::y#1 ] ] with [ zp[1]:8 [ startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 main::i#2 main::i#1 ] ] Coalescing zero page register [ zp[2]:28 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 ] ] with [ zp[2]:11 [ startProcessing::spriteData#2 startProcessing::spriteData#0 startProcessing::spriteData#1 startProcessing::$6 startProcessing::$5 main::dst#2 main::dst#0 main::dst#1 ] ] -Coalescing zero page register [ zp[1]:88 [ startProcessing::spriteCol#0 ] ] with [ zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] ] -Coalescing zero page register [ zp[1]:116 [ startProcessing::spritePtr#0 ] ] with [ zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] ] +Coalescing zero page register [ zp[1]:69 [ startProcessing::center_x#0 ] ] with [ zp[1]:27 [ init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] ] +Coalescing zero page register [ zp[1]:88 [ startProcessing::spriteCol#0 ] ] with [ zp[1]:32 [ init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] ] +Coalescing zero page register [ zp[1]:116 [ startProcessing::spritePtr#0 ] ] with [ zp[1]:33 [ init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] ] Coalescing zero page register [ zp[2]:125 [ getCharToProcess::$8 getCharToProcess::$13 getCharToProcess::$9 getCharToProcess::$10 startProcessing::$21 ] ] with [ zp[2]:48 [ heap_head#5 heap_head#1 init_angle_screen::screen_bottomline#6 init_angle_screen::screen_bottomline#0 init_angle_screen::screen_bottomline#1 init_angle_screen::screen#0 ] ] Coalescing zero page register [ zp[2]:140 [ init_angle_screen::yw#0 atan2_16::y#0 ] ] with [ zp[2]:24 [ initSprites::sp#2 initSprites::sp#1 getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 startProcessing::$9 startProcessing::$8 main::src#2 main::src#1 ] ] -Allocated (was zp[1]:27) zp[1]:2 [ init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::y#7 getCharToProcess::y#1 startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 main::i#2 main::i#1 ] +Allocated (was zp[1]:18) zp[1]:2 [ getCharToProcess::y#7 getCharToProcess::y#1 startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] Allocated (was zp[2]:28) zp[2]:3 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 startProcessing::spriteData#2 startProcessing::spriteData#0 startProcessing::spriteData#1 startProcessing::$6 startProcessing::$5 main::dst#2 main::dst#0 main::dst#1 ] Allocated (was zp[1]:50) zp[1]:5 [ processChars::i#10 processChars::i#1 ] Allocated (was zp[1]:51) zp[1]:6 [ processChars::numActive#10 processChars::numActive#3 processChars::numActive#1 ] Allocated (was zp[2]:52) zp[2]:7 [ SCREEN_COPY#0 ] Allocated (was zp[2]:54) zp[2]:9 [ SCREEN_DIST#0 malloc::mem#0 ] -Allocated (was zp[1]:67) zp[1]:11 [ main::center_y#0 startProcessing::center_y#0 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] +Allocated (was zp[1]:69) zp[1]:11 [ startProcessing::center_x#0 init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] Allocated (was zp[2]:76) zp[2]:12 [ startProcessing::$0 startProcessing::$45 startProcessing::$1 startProcessing::offset#0 startProcessing::screenPtr#0 atan2_16::yi#3 atan2_16::yi#8 atan2_16::yi#0 atan2_16::yi#16 atan2_16::$2 atan2_16::yi#1 atan2_16::yi#2 ] Allocated (was zp[2]:78) zp[2]:14 [ startProcessing::$44 atan2_16::xi#3 atan2_16::xi#8 atan2_16::xi#0 atan2_16::xi#13 atan2_16::$7 atan2_16::xi#1 atan2_16::xi#2 ] Allocated (was zp[2]:86) zp[2]:16 [ startProcessing::colPtr#0 atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 atan2_16::return#2 init_angle_screen::angle_w#0 init_angle_screen::$11 ] -Allocated (was zp[1]:88) zp[1]:18 [ startProcessing::spriteCol#0 init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] +Allocated (was zp[1]:88) zp[1]:18 [ startProcessing::spriteCol#0 init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] Allocated (was zp[2]:100) zp[2]:19 [ startProcessing::$11 startProcessing::$12 startProcessing::$13 startProcessing::spriteX#0 atan2_16::yd#5 atan2_16::yd#3 atan2_16::yd#10 atan2_16::yd#1 atan2_16::yd#2 ] Allocated (was zp[2]:108) zp[2]:21 [ startProcessing::$15 startProcessing::$16 startProcessing::$17 startProcessing::spriteY#0 atan2_16::xd#5 atan2_16::xd#3 atan2_16::xd#10 atan2_16::xd#1 atan2_16::xd#2 ] -Allocated (was zp[1]:116) zp[1]:23 [ startProcessing::spritePtr#0 init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] +Allocated (was zp[1]:116) zp[1]:23 [ startProcessing::spritePtr#0 init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] Allocated (was zp[2]:125) zp[2]:24 [ getCharToProcess::$8 getCharToProcess::$13 getCharToProcess::$9 getCharToProcess::$10 startProcessing::$21 heap_head#5 heap_head#1 init_angle_screen::screen_bottomline#6 init_angle_screen::screen_bottomline#0 init_angle_screen::screen_bottomline#1 init_angle_screen::screen#0 ] Allocated (was zp[2]:137) zp[2]:26 [ init_angle_screen::xw#0 atan2_16::x#0 getCharToProcess::$12 ] Allocated (was zp[2]:140) zp[2]:28 [ init_angle_screen::yw#0 atan2_16::y#0 initSprites::sp#2 initSprites::sp#1 getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 startProcessing::$9 startProcessing::$8 main::src#2 main::src#1 ] -Allocated (was zp[1]:152) zp[1]:30 [ init_angle_screen::ang_w#0 startProcessing::center_x#0 ] +Allocated (was zp[1]:152) zp[1]:30 [ init_angle_screen::ang_w#0 main::center_y#0 startProcessing::center_y#0 ] Allocated (was zp[2]:165) zp[2]:31 [ processChars::processing#0 ] Allocated (was zp[1]:167) zp[1]:33 [ processChars::bitmask#0 ] Allocated (was zp[2]:168) zp[2]:34 [ processChars::xpos#0 processChars::$23 ] @@ -7902,8 +7871,7 @@ __bend: main: { .label dst = 3 .label src = $1c - .label i = 2 - .label center_y = $b + .label center_y = $1e // [9] (byte*) init_angle_screen::screen#0 ← (byte*)(void*) SCREEN_DIST#0 -- pbuz1=pbuz2 lda.z SCREEN_DIST sta.z init_angle_screen.screen @@ -7940,9 +7908,8 @@ main: { bne __b2 // [14] phi from main::@1 to main::@3 [phi:main::@1->main::@3] __b3_from___b1: - // [14] phi (byte) main::i#2 = (byte) 0 [phi:main::@1->main::@3#0] -- vbuz1=vbuc1 - lda #0 - sta.z i + // [14] phi (byte) main::i#2 = (byte) 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1 + ldx #0 jmp __b3 // Init processing array // [14] phi from main::@3 to main::@3 [phi:main::@3->main::@3] @@ -7951,62 +7918,63 @@ main: { jmp __b3 // main::@3 __b3: - // [15] (byte~) main::$20 ← (byte) main::i#2 << (byte) 1 -- vbuaa=vbuz1_rol_1 - lda.z i + // [15] (byte~) main::$20 ← (byte) main::i#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa asl - // [16] (byte~) main::$21 ← (byte~) main::$20 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuz1 + // [16] (byte~) main::$21 ← (byte~) main::$20 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx.z $ff clc - adc.z i + adc.z $ff // [17] (byte~) main::$22 ← (byte~) main::$21 << (byte) 1 -- vbuaa=vbuaa_rol_1 asl - // [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuz1 + // [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx.z $ff clc - adc.z i - // [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 -- vbuxx=vbuaa_rol_1 + adc.z $ff + // [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 -- vbuyy=vbuaa_rol_1 asl - tax - // [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING,x - lda #0 - sta PROCESSING+1,x - // [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y,x - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y+1,x - // [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,x - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,x - // [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,x - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,x - // [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_ID,x - // [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_PTR,x - // [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_COL,x - // [27] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_STATUS + (byte~) main::$10) ← (const byte) STATUS_FREE -- pbuc1_derefidx_vbuxx=vbuc2 - lda #STATUS_FREE - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_STATUS,x - // [28] *((byte**)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR + (byte~) main::$10) ← (byte*) 0 -- pptc1_derefidx_vbuxx=pbuc2 + tay + // [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 lda #<0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR,x + sta PROCESSING,y lda #>0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR+1,x - // [29] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 - inc.z i - // [30] if((byte) main::i#1!=(const byte) NUM_PROCESSING-(byte) 1+(byte) 1) goto main::@3 -- vbuz1_neq_vbuc1_then_la1 - lda #NUM_PROCESSING-1+1 - cmp.z i + sta PROCESSING+1,y + // [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 + lda #<0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y,y + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y+1,y + // [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 + lda #<0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,y + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,y + // [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 + lda #<0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,y + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,y + // [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuyy=vbuc2 + lda #0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_ID,y + // [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuyy=vbuc2 + lda #0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_PTR,y + // [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuyy=vbuc2 + lda #0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_COL,y + // [27] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_STATUS + (byte~) main::$10) ← (const byte) STATUS_FREE -- pbuc1_derefidx_vbuyy=vbuc2 + lda #STATUS_FREE + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_STATUS,y + // [28] *((byte**)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR + (byte~) main::$10) ← (byte*) 0 -- pptc1_derefidx_vbuyy=pbuc2 + lda #<0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR,y + lda #>0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR+1,y + // [29] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + inx + // [30] if((byte) main::i#1!=(const byte) NUM_PROCESSING-(byte) 1+(byte) 1) goto main::@3 -- vbuxx_neq_vbuc1_then_la1 + cpx #NUM_PROCESSING-1+1 bne __b3_from___b3 // [31] phi from main::@3 to main::@4 [phi:main::@3->main::@4] __b4_from___b3: @@ -8096,7 +8064,7 @@ main: { } // startProcessing // Start processing a char - by inserting it into the PROCESSING array -// startProcessing(byte zp($1e) center_x, byte zp($b) center_y) +// startProcessing(byte zp($b) center_x, byte zp($1e) center_y) startProcessing: { .label __0 = $c .label __1 = $c @@ -8111,8 +8079,8 @@ startProcessing: { .label __16 = $15 .label __17 = $15 .label __21 = $18 - .label center_x = $1e - .label center_y = $b + .label center_x = $b + .label center_y = $1e .label i = 2 .label offset = $c .label colPtr = $10 @@ -8434,10 +8402,10 @@ startProcessing: { sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,x lda.z __21+1 sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,x - // [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c -- pwuc1_derefidx_vbuxx=vbuc2 - lda #$3c + // [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c -- pwuc1_derefidx_vbuxx=vwuc2 + lda #<$3c sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,x - lda #0 + lda #>$3c sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,x // [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 -- pbuc1_derefidx_vbuxx=vbuz1 lda.z freeIdx @@ -8494,11 +8462,11 @@ getCharToProcess: { .label screen_line = $1c .label dist_line = 3 .label y = 2 - .label return_x = $17 - .label return_y = $b - .label closest_dist = $12 - .label closest_x = $17 - .label closest_y = $b + .label return_x = $12 + .label return_y = $17 + .label closest_dist = $b + .label closest_x = $12 + .label closest_y = $17 .label __12 = $1a .label __13 = $18 // [118] (byte*) getCharToProcess::screen_line#0 ← (byte*)(void*) SCREEN_COPY#0 -- pbuz1=pbuz2 @@ -8832,7 +8800,7 @@ init_angle_screen: { .label ang_w = $1e .label x = $12 .label xb = $17 - .label y = 2 + .label y = $b // [169] (byte*) init_angle_screen::screen_topline#0 ← (byte*) init_angle_screen::screen#0 + (word)(number) $28*(number) $c -- pbuz1=pbuz2_plus_vwuc1 lda.z screen clc @@ -9865,13 +9833,13 @@ Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination -Removing instruction lda #0 -Removing instruction lda #0 -Removing instruction lda #0 -Removing instruction lda #0 -Removing instruction lda #0 -Removing instruction lda #0 -Removing instruction lda #0 +Removing instruction lda #>0 +Removing instruction lda #<0 +Removing instruction lda #>0 +Removing instruction lda #<0 +Removing instruction lda #>0 +Removing instruction lda #<0 +Removing instruction lda #>0 Removing instruction lda #0 Removing instruction lda #0 Removing instruction lda #0 @@ -10041,23 +10009,23 @@ Removing instruction jmp __b1 Succesful ASM optimization Pass5NextJumpElimination Removing instruction ldy #OFFSET_STRUCT_PROCESSINGSPRITE_STATUS Succesful ASM optimization Pass5UnnecesaryLoadElimination -Fixing long branch [460] bne __b2 to beq -Fixing long branch [875] beq __b12 to bne -Fixing long branch [1218] bne __b1 to beq -Fixing long branch [236] bne __b3 to beq -Fixing long branch [242] beq __b8 to bne -Fixing long branch [505] beq __b11 to bne -Fixing long branch [775] bpl __b1 to bmi -Fixing long branch [787] bpl __b4 to bmi -Fixing long branch [1032] beq __b2 to bne -Fixing long branch [1092] bne __b4 to beq -Fixing long branch [1126] bcc __b6 to bcs -Fixing long branch [1133] bcc __b6 to bcs -Fixing long branch [1140] bcc __b6 to bcs -Fixing long branch [1147] bcc __b6 to bcs -Fixing long branch [1155] bcc __b6 to bcs -Fixing long branch [1162] bcc __b6 to bcs -Fixing long branch [1170] bcc __b6 to bcs +Fixing long branch [459] bne __b2 to beq +Fixing long branch [874] beq __b12 to bne +Fixing long branch [1217] bne __b1 to beq +Fixing long branch [235] bne __b3 to beq +Fixing long branch [241] beq __b8 to bne +Fixing long branch [504] beq __b11 to bne +Fixing long branch [774] bpl __b1 to bmi +Fixing long branch [786] bpl __b4 to bmi +Fixing long branch [1031] beq __b2 to bne +Fixing long branch [1091] bne __b4 to beq +Fixing long branch [1125] bcc __b6 to bcs +Fixing long branch [1132] bcc __b6 to bcs +Fixing long branch [1139] bcc __b6 to bcs +Fixing long branch [1146] bcc __b6 to bcs +Fixing long branch [1154] bcc __b6 to bcs +Fixing long branch [1161] bcc __b6 to bcs +Fixing long branch [1169] bcc __b6 to bcs FINAL SYMBOL TABLE (label) @1 @@ -10247,16 +10215,16 @@ FINAL SYMBOL TABLE (label) getCharToProcess::@9 (label) getCharToProcess::@return (byte) getCharToProcess::closest_dist -(byte) getCharToProcess::closest_dist#10 closest_dist zp[1]:18 202.0 -(byte) getCharToProcess::closest_dist#12 closest_dist zp[1]:18 2002.0 -(byte) getCharToProcess::closest_dist#2 closest_dist zp[1]:18 1026.25 -(byte) getCharToProcess::closest_dist#8 closest_dist zp[1]:18 202.0 +(byte) getCharToProcess::closest_dist#10 closest_dist zp[1]:11 202.0 +(byte) getCharToProcess::closest_dist#12 closest_dist zp[1]:11 2002.0 +(byte) getCharToProcess::closest_dist#2 closest_dist zp[1]:11 1026.25 +(byte) getCharToProcess::closest_dist#8 closest_dist zp[1]:11 202.0 (byte) getCharToProcess::closest_x -(byte) getCharToProcess::closest_x#7 closest_x zp[1]:23 517.3333333333334 -(byte) getCharToProcess::closest_x#9 closest_x zp[1]:23 202.0 +(byte) getCharToProcess::closest_x#7 closest_x zp[1]:18 517.3333333333334 +(byte) getCharToProcess::closest_x#9 closest_x zp[1]:18 202.0 (byte) getCharToProcess::closest_y -(byte) getCharToProcess::closest_y#7 closest_y zp[1]:11 517.3333333333334 -(byte) getCharToProcess::closest_y#9 closest_y zp[1]:11 202.0 +(byte) getCharToProcess::closest_y#7 closest_y zp[1]:23 517.3333333333334 +(byte) getCharToProcess::closest_y#9 closest_y zp[1]:23 202.0 (byte) getCharToProcess::dist (byte) getCharToProcess::dist#0 reg byte x 750.75 (byte*) getCharToProcess::dist_line @@ -10271,12 +10239,12 @@ FINAL SYMBOL TABLE (byte) getCharToProcess::return_dist#6 reg byte x 2002.0 (byte) getCharToProcess::return_x (byte) getCharToProcess::return_x#0 reg byte y 7.333333333333333 -(byte) getCharToProcess::return_x#1 return_x zp[1]:23 228.7777777777778 -(byte) getCharToProcess::return_x#7 return_x zp[1]:23 1001.0 +(byte) getCharToProcess::return_x#1 return_x zp[1]:18 228.7777777777778 +(byte) getCharToProcess::return_x#7 return_x zp[1]:18 1001.0 (byte) getCharToProcess::return_y (byte) getCharToProcess::return_y#0 reg byte a 7.333333333333333 -(byte) getCharToProcess::return_y#1 return_y zp[1]:11 216.6315789473684 -(byte) getCharToProcess::return_y#7 return_y zp[1]:11 2002.0 +(byte) getCharToProcess::return_y#1 return_y zp[1]:23 216.6315789473684 +(byte) getCharToProcess::return_y#7 return_y zp[1]:23 2002.0 (byte*) getCharToProcess::screen_line (byte*) getCharToProcess::screen_line#0 screen_line zp[2]:28 2.0 (byte*) getCharToProcess::screen_line#1 screen_line zp[2]:28 40.4 @@ -10339,8 +10307,8 @@ FINAL SYMBOL TABLE (signed word) init_angle_screen::xw (word) init_angle_screen::xw#0 xw zp[2]:26 33.666666666666664 (byte) init_angle_screen::y -(byte) init_angle_screen::y#1 y zp[1]:2 16.5 -(byte) init_angle_screen::y#5 y zp[1]:2 4.730769230769231 +(byte) init_angle_screen::y#1 y zp[1]:11 16.5 +(byte) init_angle_screen::y#5 y zp[1]:11 4.730769230769231 (signed word) init_angle_screen::yw (word) init_angle_screen::yw#0 yw zp[2]:28 50.5 interrupt(HARDWARE_ALL)(void()) irqBottom() @@ -10354,7 +10322,7 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (byte) irqTop::i (byte) irqTop::i1 (void()) main() -(byte~) main::$10 reg byte x 12.222222222222221 +(byte~) main::$10 reg byte y 12.222222222222221 (byte~) main::$20 reg byte a 22.0 (byte~) main::$21 reg byte a 22.0 (byte~) main::$22 reg byte a 22.0 @@ -10376,14 +10344,14 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (byte) main::center_x (byte) main::center_x#0 reg byte y 5.5 (byte) main::center_y -(byte) main::center_y#0 center_y zp[1]:11 5.5 +(byte) main::center_y#0 center_y zp[1]:30 5.5 (byte*) main::dst (byte*) main::dst#0 dst zp[2]:3 4.0 (byte*) main::dst#1 dst zp[2]:3 22.0 (byte*) main::dst#2 dst zp[2]:3 8.75 (byte) main::i -(byte) main::i#1 i zp[1]:2 16.5 -(byte) main::i#2 i zp[1]:2 3.6666666666666665 +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 3.6666666666666665 (byte*) main::src (byte*) main::src#1 src zp[2]:28 11.0 (byte*) main::src#2 src zp[2]:28 14.666666666666666 @@ -10491,9 +10459,9 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (struct ProcessingChar) startProcessing::center (byte) startProcessing::center_dist (byte) startProcessing::center_x -(byte) startProcessing::center_x#0 center_x zp[1]:30 0.30952380952380953 +(byte) startProcessing::center_x#0 center_x zp[1]:11 0.30952380952380953 (byte) startProcessing::center_y -(byte) startProcessing::center_y#0 center_y zp[1]:11 0.24444444444444444 +(byte) startProcessing::center_y#0 center_y zp[1]:30 0.24444444444444444 (byte) startProcessing::ch (byte) startProcessing::ch#0 reg byte a 2.0 (byte*) startProcessing::chargenData @@ -10531,12 +10499,13 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (word) startProcessing::spriteY (word) startProcessing::spriteY#0 spriteY zp[2]:21 0.4 +reg byte x [ main::i#2 main::i#1 ] reg byte x [ startProcessing::freeIdx#6 startProcessing::freeIdx#7 ] reg byte x [ startProcessing::i1#2 startProcessing::i1#1 ] +zp[1]:2 [ getCharToProcess::y#7 getCharToProcess::y#1 startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] reg byte y [ getCharToProcess::x#2 getCharToProcess::x#1 ] reg byte x [ getCharToProcess::return_dist#1 getCharToProcess::return_dist#5 getCharToProcess::return_dist#6 getCharToProcess::dist#0 ] reg byte x [ initSprites::i#2 initSprites::i#1 ] -zp[1]:2 [ init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::y#7 getCharToProcess::y#1 startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 main::i#2 main::i#1 ] zp[2]:3 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 startProcessing::spriteData#2 startProcessing::spriteData#0 startProcessing::spriteData#1 startProcessing::$6 startProcessing::$5 main::dst#2 main::dst#0 main::dst#1 ] reg byte x [ atan2_16::i#2 atan2_16::i#1 ] reg byte y [ atan2_16::shift#2 atan2_16::shift#5 atan2_16::shift#1 ] @@ -10548,13 +10517,13 @@ reg byte a [ main::$20 ] reg byte a [ main::$21 ] reg byte a [ main::$22 ] reg byte a [ main::$23 ] -reg byte x [ main::$10 ] +reg byte y [ main::$10 ] reg byte y [ getCharToProcess::return_x#0 ] reg byte a [ getCharToProcess::return_y#0 ] reg byte x [ getCharToProcess::return_dist#0 ] reg byte y [ main::center_x#0 ] -zp[1]:11 [ main::center_y#0 startProcessing::center_y#0 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] reg byte a [ main::center_dist#0 ] +zp[1]:11 [ startProcessing::center_x#0 init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] reg byte a [ startProcessing::$39 ] reg byte a [ startProcessing::$40 ] reg byte a [ startProcessing::$41 ] @@ -10563,11 +10532,11 @@ reg byte a [ startProcessing::$27 ] zp[2]:12 [ startProcessing::$0 startProcessing::$45 startProcessing::$1 startProcessing::offset#0 startProcessing::screenPtr#0 atan2_16::yi#3 atan2_16::yi#8 atan2_16::yi#0 atan2_16::yi#16 atan2_16::$2 atan2_16::yi#1 atan2_16::yi#2 ] zp[2]:14 [ startProcessing::$44 atan2_16::xi#3 atan2_16::xi#8 atan2_16::xi#0 atan2_16::xi#13 atan2_16::$7 atan2_16::xi#1 atan2_16::xi#2 ] zp[2]:16 [ startProcessing::colPtr#0 atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 atan2_16::return#2 init_angle_screen::angle_w#0 init_angle_screen::$11 ] -zp[1]:18 [ startProcessing::spriteCol#0 init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] +zp[1]:18 [ startProcessing::spriteCol#0 init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] reg byte a [ startProcessing::ch#0 ] zp[2]:19 [ startProcessing::$11 startProcessing::$12 startProcessing::$13 startProcessing::spriteX#0 atan2_16::yd#5 atan2_16::yd#3 atan2_16::yd#10 atan2_16::yd#1 atan2_16::yd#2 ] zp[2]:21 [ startProcessing::$15 startProcessing::$16 startProcessing::$17 startProcessing::spriteY#0 atan2_16::xd#5 atan2_16::xd#3 atan2_16::xd#10 atan2_16::xd#1 atan2_16::xd#2 ] -zp[1]:23 [ startProcessing::spritePtr#0 init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] +zp[1]:23 [ startProcessing::spritePtr#0 init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] reg byte a [ startProcessing::$20 ] reg byte a [ startProcessing::$47 ] reg byte a [ startProcessing::$48 ] @@ -10580,7 +10549,7 @@ reg byte a [ init_angle_screen::$4 ] zp[2]:26 [ init_angle_screen::xw#0 atan2_16::x#0 getCharToProcess::$12 ] reg byte a [ init_angle_screen::$7 ] zp[2]:28 [ init_angle_screen::yw#0 atan2_16::y#0 initSprites::sp#2 initSprites::sp#1 getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 startProcessing::$9 startProcessing::$8 main::src#2 main::src#1 ] -zp[1]:30 [ init_angle_screen::ang_w#0 startProcessing::center_x#0 ] +zp[1]:30 [ init_angle_screen::ang_w#0 main::center_y#0 startProcessing::center_y#0 ] reg byte a [ init_angle_screen::$13 ] reg byte a [ init_angle_screen::$14 ] reg byte a [ init_angle_screen::$15 ] @@ -10610,7 +10579,7 @@ reg byte a [ processChars::$29 ] FINAL ASSEMBLER -Score: 1113922 +Score: 1113882 // File Comments // Clears start screen throwing around the letters (by turning them into sprites) @@ -10734,8 +10703,7 @@ __b1: main: { .label dst = 3 .label src = $1c - .label i = 2 - .label center_y = $b + .label center_y = $1e // init_angle_screen(SCREEN_DIST) // [9] (byte*) init_angle_screen::screen#0 ← (byte*)(void*) SCREEN_DIST#0 -- pbuz1=pbuz2 lda.z SCREEN_DIST @@ -10770,61 +10738,61 @@ main: { cmp #main::@3] - // [14] phi (byte) main::i#2 = (byte) 0 [phi:main::@1->main::@3#0] -- vbuz1=vbuc1 - lda #0 - sta.z i + // [14] phi (byte) main::i#2 = (byte) 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1 + ldx #0 // Init processing array // [14] phi from main::@3 to main::@3 [phi:main::@3->main::@3] // [14] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@3->main::@3#0] -- register_copy // main::@3 __b3: // PROCESSING[i] = { 0, 0, 0, 0, 0, 0, 0, STATUS_FREE, 0} - // [15] (byte~) main::$20 ← (byte) main::i#2 << (byte) 1 -- vbuaa=vbuz1_rol_1 - lda.z i + // [15] (byte~) main::$20 ← (byte) main::i#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa asl - // [16] (byte~) main::$21 ← (byte~) main::$20 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuz1 + // [16] (byte~) main::$21 ← (byte~) main::$20 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx.z $ff clc - adc.z i + adc.z $ff // [17] (byte~) main::$22 ← (byte~) main::$21 << (byte) 1 -- vbuaa=vbuaa_rol_1 asl - // [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuz1 + // [18] (byte~) main::$23 ← (byte~) main::$22 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx.z $ff clc - adc.z i - // [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 -- vbuxx=vbuaa_rol_1 + adc.z $ff + // [19] (byte~) main::$10 ← (byte~) main::$23 << (byte) 1 -- vbuyy=vbuaa_rol_1 asl - tax - // [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - lda #0 - sta PROCESSING,x - sta PROCESSING+1,x - // [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y,x - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y+1,x - // [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,x - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,x - // [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (byte) 0 -- pwuc1_derefidx_vbuxx=vbuc2 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,x - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,x - // [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_ID,x - // [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_PTR,x - // [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_COL,x - // [27] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_STATUS + (byte~) main::$10) ← (const byte) STATUS_FREE -- pbuc1_derefidx_vbuxx=vbuc2 - lda #STATUS_FREE - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_STATUS,x - // [28] *((byte**)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR + (byte~) main::$10) ← (byte*) 0 -- pptc1_derefidx_vbuxx=pbuc2 + tay + // [20] *((word*)(const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 lda #<0 - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR,x - sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR+1,x + sta PROCESSING,y + sta PROCESSING+1,y + // [21] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_Y + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y,y + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_Y+1,y + // [22] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VX + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,y + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,y + // [23] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) main::$10) ← (word) 0 -- pwuc1_derefidx_vbuyy=vwuc2 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,y + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,y + // [24] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuyy=vbuc2 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_ID,y + // [25] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_PTR + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuyy=vbuc2 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_PTR,y + // [26] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_COL + (byte~) main::$10) ← (byte) 0 -- pbuc1_derefidx_vbuyy=vbuc2 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_COL,y + // [27] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_STATUS + (byte~) main::$10) ← (const byte) STATUS_FREE -- pbuc1_derefidx_vbuyy=vbuc2 + lda #STATUS_FREE + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_STATUS,y + // [28] *((byte**)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR + (byte~) main::$10) ← (byte*) 0 -- pptc1_derefidx_vbuyy=pbuc2 + lda #<0 + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR,y + sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_SCREENPTR+1,y // for( byte i: 0..NUM_PROCESSING-1 ) - // [29] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 - inc.z i - // [30] if((byte) main::i#1!=(const byte) NUM_PROCESSING-(byte) 1+(byte) 1) goto main::@3 -- vbuz1_neq_vbuc1_then_la1 - lda #NUM_PROCESSING-1+1 - cmp.z i + // [29] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + inx + // [30] if((byte) main::i#1!=(const byte) NUM_PROCESSING-(byte) 1+(byte) 1) goto main::@3 -- vbuxx_neq_vbuc1_then_la1 + cpx #NUM_PROCESSING-1+1 bne __b3 // [31] phi from main::@3 to main::@4 [phi:main::@3->main::@4] // main::@4 @@ -10906,7 +10874,7 @@ main: { } // startProcessing // Start processing a char - by inserting it into the PROCESSING array -// startProcessing(byte zp($1e) center_x, byte zp($b) center_y) +// startProcessing(byte zp($b) center_x, byte zp($1e) center_y) startProcessing: { .label __0 = $c .label __1 = $c @@ -10921,8 +10889,8 @@ startProcessing: { .label __16 = $15 .label __17 = $15 .label __21 = $18 - .label center_x = $1e - .label center_y = $b + .label center_x = $b + .label center_y = $1e .label i = 2 .label offset = $c .label colPtr = $10 @@ -11265,10 +11233,10 @@ startProcessing: { sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX,x lda.z __21+1 sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VX+1,x - // [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (byte) $3c -- pwuc1_derefidx_vbuxx=vbuc2 - lda #$3c + // [107] *((word*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_VY + (byte~) startProcessing::$28) ← (word) $3c -- pwuc1_derefidx_vbuxx=vwuc2 + lda #<$3c sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY,x - lda #0 + lda #>$3c sta PROCESSING+OFFSET_STRUCT_PROCESSINGSPRITE_VY+1,x // [108] *((byte*)(const struct ProcessingSprite*) PROCESSING+(const byte) OFFSET_STRUCT_PROCESSINGSPRITE_ID + (byte~) startProcessing::$28) ← (byte) startProcessing::freeIdx#2 -- pbuc1_derefidx_vbuxx=vbuz1 lda.z freeIdx @@ -11324,11 +11292,11 @@ getCharToProcess: { .label screen_line = $1c .label dist_line = 3 .label y = 2 - .label return_x = $17 - .label return_y = $b - .label closest_dist = $12 - .label closest_x = $17 - .label closest_y = $b + .label return_x = $12 + .label return_y = $17 + .label closest_dist = $b + .label closest_x = $12 + .label closest_y = $17 .label __12 = $1a .label __13 = $18 // screen_line = SCREEN_COPY @@ -11656,7 +11624,7 @@ init_angle_screen: { .label ang_w = $1e .label x = $12 .label xb = $17 - .label y = 2 + .label y = $b // screen_topline = screen+40*12 // [169] (byte*) init_angle_screen::screen_topline#0 ← (byte*) init_angle_screen::screen#0 + (word)(number) $28*(number) $c -- pbuz1=pbuz2_plus_vwuc1 lda.z screen diff --git a/src/test/ref/complex/clearscreen/clearscreen.sym b/src/test/ref/complex/clearscreen/clearscreen.sym index 089d00b35..f213a3c28 100644 --- a/src/test/ref/complex/clearscreen/clearscreen.sym +++ b/src/test/ref/complex/clearscreen/clearscreen.sym @@ -185,16 +185,16 @@ (label) getCharToProcess::@9 (label) getCharToProcess::@return (byte) getCharToProcess::closest_dist -(byte) getCharToProcess::closest_dist#10 closest_dist zp[1]:18 202.0 -(byte) getCharToProcess::closest_dist#12 closest_dist zp[1]:18 2002.0 -(byte) getCharToProcess::closest_dist#2 closest_dist zp[1]:18 1026.25 -(byte) getCharToProcess::closest_dist#8 closest_dist zp[1]:18 202.0 +(byte) getCharToProcess::closest_dist#10 closest_dist zp[1]:11 202.0 +(byte) getCharToProcess::closest_dist#12 closest_dist zp[1]:11 2002.0 +(byte) getCharToProcess::closest_dist#2 closest_dist zp[1]:11 1026.25 +(byte) getCharToProcess::closest_dist#8 closest_dist zp[1]:11 202.0 (byte) getCharToProcess::closest_x -(byte) getCharToProcess::closest_x#7 closest_x zp[1]:23 517.3333333333334 -(byte) getCharToProcess::closest_x#9 closest_x zp[1]:23 202.0 +(byte) getCharToProcess::closest_x#7 closest_x zp[1]:18 517.3333333333334 +(byte) getCharToProcess::closest_x#9 closest_x zp[1]:18 202.0 (byte) getCharToProcess::closest_y -(byte) getCharToProcess::closest_y#7 closest_y zp[1]:11 517.3333333333334 -(byte) getCharToProcess::closest_y#9 closest_y zp[1]:11 202.0 +(byte) getCharToProcess::closest_y#7 closest_y zp[1]:23 517.3333333333334 +(byte) getCharToProcess::closest_y#9 closest_y zp[1]:23 202.0 (byte) getCharToProcess::dist (byte) getCharToProcess::dist#0 reg byte x 750.75 (byte*) getCharToProcess::dist_line @@ -209,12 +209,12 @@ (byte) getCharToProcess::return_dist#6 reg byte x 2002.0 (byte) getCharToProcess::return_x (byte) getCharToProcess::return_x#0 reg byte y 7.333333333333333 -(byte) getCharToProcess::return_x#1 return_x zp[1]:23 228.7777777777778 -(byte) getCharToProcess::return_x#7 return_x zp[1]:23 1001.0 +(byte) getCharToProcess::return_x#1 return_x zp[1]:18 228.7777777777778 +(byte) getCharToProcess::return_x#7 return_x zp[1]:18 1001.0 (byte) getCharToProcess::return_y (byte) getCharToProcess::return_y#0 reg byte a 7.333333333333333 -(byte) getCharToProcess::return_y#1 return_y zp[1]:11 216.6315789473684 -(byte) getCharToProcess::return_y#7 return_y zp[1]:11 2002.0 +(byte) getCharToProcess::return_y#1 return_y zp[1]:23 216.6315789473684 +(byte) getCharToProcess::return_y#7 return_y zp[1]:23 2002.0 (byte*) getCharToProcess::screen_line (byte*) getCharToProcess::screen_line#0 screen_line zp[2]:28 2.0 (byte*) getCharToProcess::screen_line#1 screen_line zp[2]:28 40.4 @@ -277,8 +277,8 @@ (signed word) init_angle_screen::xw (word) init_angle_screen::xw#0 xw zp[2]:26 33.666666666666664 (byte) init_angle_screen::y -(byte) init_angle_screen::y#1 y zp[1]:2 16.5 -(byte) init_angle_screen::y#5 y zp[1]:2 4.730769230769231 +(byte) init_angle_screen::y#1 y zp[1]:11 16.5 +(byte) init_angle_screen::y#5 y zp[1]:11 4.730769230769231 (signed word) init_angle_screen::yw (word) init_angle_screen::yw#0 yw zp[2]:28 50.5 interrupt(HARDWARE_ALL)(void()) irqBottom() @@ -292,7 +292,7 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (byte) irqTop::i (byte) irqTop::i1 (void()) main() -(byte~) main::$10 reg byte x 12.222222222222221 +(byte~) main::$10 reg byte y 12.222222222222221 (byte~) main::$20 reg byte a 22.0 (byte~) main::$21 reg byte a 22.0 (byte~) main::$22 reg byte a 22.0 @@ -314,14 +314,14 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (byte) main::center_x (byte) main::center_x#0 reg byte y 5.5 (byte) main::center_y -(byte) main::center_y#0 center_y zp[1]:11 5.5 +(byte) main::center_y#0 center_y zp[1]:30 5.5 (byte*) main::dst (byte*) main::dst#0 dst zp[2]:3 4.0 (byte*) main::dst#1 dst zp[2]:3 22.0 (byte*) main::dst#2 dst zp[2]:3 8.75 (byte) main::i -(byte) main::i#1 i zp[1]:2 16.5 -(byte) main::i#2 i zp[1]:2 3.6666666666666665 +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 3.6666666666666665 (byte*) main::src (byte*) main::src#1 src zp[2]:28 11.0 (byte*) main::src#2 src zp[2]:28 14.666666666666666 @@ -429,9 +429,9 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (struct ProcessingChar) startProcessing::center (byte) startProcessing::center_dist (byte) startProcessing::center_x -(byte) startProcessing::center_x#0 center_x zp[1]:30 0.30952380952380953 +(byte) startProcessing::center_x#0 center_x zp[1]:11 0.30952380952380953 (byte) startProcessing::center_y -(byte) startProcessing::center_y#0 center_y zp[1]:11 0.24444444444444444 +(byte) startProcessing::center_y#0 center_y zp[1]:30 0.24444444444444444 (byte) startProcessing::ch (byte) startProcessing::ch#0 reg byte a 2.0 (byte*) startProcessing::chargenData @@ -469,12 +469,13 @@ interrupt(HARDWARE_ALL)(void()) irqTop() (word) startProcessing::spriteY (word) startProcessing::spriteY#0 spriteY zp[2]:21 0.4 +reg byte x [ main::i#2 main::i#1 ] reg byte x [ startProcessing::freeIdx#6 startProcessing::freeIdx#7 ] reg byte x [ startProcessing::i1#2 startProcessing::i1#1 ] +zp[1]:2 [ getCharToProcess::y#7 getCharToProcess::y#1 startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 ] reg byte y [ getCharToProcess::x#2 getCharToProcess::x#1 ] reg byte x [ getCharToProcess::return_dist#1 getCharToProcess::return_dist#5 getCharToProcess::return_dist#6 getCharToProcess::dist#0 ] reg byte x [ initSprites::i#2 initSprites::i#1 ] -zp[1]:2 [ init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::y#7 getCharToProcess::y#1 startProcessing::freeIdx#2 startProcessing::freeIdx#8 startProcessing::i#2 startProcessing::i#1 main::i#2 main::i#1 ] zp[2]:3 [ init_angle_screen::screen_topline#6 init_angle_screen::screen_topline#0 init_angle_screen::screen_topline#1 getCharToProcess::dist_line#6 getCharToProcess::dist_line#0 getCharToProcess::dist_line#1 startProcessing::spriteData#2 startProcessing::spriteData#0 startProcessing::spriteData#1 startProcessing::$6 startProcessing::$5 main::dst#2 main::dst#0 main::dst#1 ] reg byte x [ atan2_16::i#2 atan2_16::i#1 ] reg byte y [ atan2_16::shift#2 atan2_16::shift#5 atan2_16::shift#1 ] @@ -486,13 +487,13 @@ reg byte a [ main::$20 ] reg byte a [ main::$21 ] reg byte a [ main::$22 ] reg byte a [ main::$23 ] -reg byte x [ main::$10 ] +reg byte y [ main::$10 ] reg byte y [ getCharToProcess::return_x#0 ] reg byte a [ getCharToProcess::return_y#0 ] reg byte x [ getCharToProcess::return_dist#0 ] reg byte y [ main::center_x#0 ] -zp[1]:11 [ main::center_y#0 startProcessing::center_y#0 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] reg byte a [ main::center_dist#0 ] +zp[1]:11 [ startProcessing::center_x#0 init_angle_screen::y#5 init_angle_screen::y#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] reg byte a [ startProcessing::$39 ] reg byte a [ startProcessing::$40 ] reg byte a [ startProcessing::$41 ] @@ -501,11 +502,11 @@ reg byte a [ startProcessing::$27 ] zp[2]:12 [ startProcessing::$0 startProcessing::$45 startProcessing::$1 startProcessing::offset#0 startProcessing::screenPtr#0 atan2_16::yi#3 atan2_16::yi#8 atan2_16::yi#0 atan2_16::yi#16 atan2_16::$2 atan2_16::yi#1 atan2_16::yi#2 ] zp[2]:14 [ startProcessing::$44 atan2_16::xi#3 atan2_16::xi#8 atan2_16::xi#0 atan2_16::xi#13 atan2_16::$7 atan2_16::xi#1 atan2_16::xi#2 ] zp[2]:16 [ startProcessing::colPtr#0 atan2_16::angle#6 atan2_16::angle#12 atan2_16::angle#13 atan2_16::angle#2 atan2_16::angle#3 atan2_16::return#0 atan2_16::angle#5 atan2_16::angle#11 atan2_16::angle#1 atan2_16::angle#4 atan2_16::return#2 init_angle_screen::angle_w#0 init_angle_screen::$11 ] -zp[1]:18 [ startProcessing::spriteCol#0 init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_dist#2 getCharToProcess::closest_dist#8 getCharToProcess::closest_dist#10 getCharToProcess::closest_dist#12 ] +zp[1]:18 [ startProcessing::spriteCol#0 init_angle_screen::x#2 init_angle_screen::x#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] reg byte a [ startProcessing::ch#0 ] zp[2]:19 [ startProcessing::$11 startProcessing::$12 startProcessing::$13 startProcessing::spriteX#0 atan2_16::yd#5 atan2_16::yd#3 atan2_16::yd#10 atan2_16::yd#1 atan2_16::yd#2 ] zp[2]:21 [ startProcessing::$15 startProcessing::$16 startProcessing::$17 startProcessing::spriteY#0 atan2_16::xd#5 atan2_16::xd#3 atan2_16::xd#10 atan2_16::xd#1 atan2_16::xd#2 ] -zp[1]:23 [ startProcessing::spritePtr#0 init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_x#7 getCharToProcess::closest_x#9 getCharToProcess::return_x#1 getCharToProcess::return_x#7 ] +zp[1]:23 [ startProcessing::spritePtr#0 init_angle_screen::xb#2 init_angle_screen::xb#1 getCharToProcess::closest_y#7 getCharToProcess::closest_y#9 getCharToProcess::return_y#1 getCharToProcess::return_y#7 ] reg byte a [ startProcessing::$20 ] reg byte a [ startProcessing::$47 ] reg byte a [ startProcessing::$48 ] @@ -518,7 +519,7 @@ reg byte a [ init_angle_screen::$4 ] zp[2]:26 [ init_angle_screen::xw#0 atan2_16::x#0 getCharToProcess::$12 ] reg byte a [ init_angle_screen::$7 ] zp[2]:28 [ init_angle_screen::yw#0 atan2_16::y#0 initSprites::sp#2 initSprites::sp#1 getCharToProcess::screen_line#4 getCharToProcess::screen_line#0 getCharToProcess::screen_line#1 startProcessing::chargenData#2 startProcessing::chargenData#0 startProcessing::chargenData#1 startProcessing::$9 startProcessing::$8 main::src#2 main::src#1 ] -zp[1]:30 [ init_angle_screen::ang_w#0 startProcessing::center_x#0 ] +zp[1]:30 [ init_angle_screen::ang_w#0 main::center_y#0 startProcessing::center_y#0 ] reg byte a [ init_angle_screen::$13 ] reg byte a [ init_angle_screen::$14 ] reg byte a [ init_angle_screen::$15 ] diff --git a/src/test/ref/complex/splines/truetype-splines.log b/src/test/ref/complex/splines/truetype-splines.log index d9a38ec34..5deb50fed 100644 --- a/src/test/ref/complex/splines/truetype-splines.log +++ b/src/test/ref/complex/splines/truetype-splines.log @@ -18,6 +18,22 @@ Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (nu Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (byte) bitmap_plot_spline_8seg::n) Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (byte) bitmap_plot_spline_8seg::n) Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (byte) bitmap_plot_spline_8seg::n) +Constantified RValue *((const struct SplineVector16*) SPLINE_16SEG + (byte~) spline_16seg::$49) ← (struct SplineVector16){ (signed word~) spline_16seg::$40, (signed word~) spline_16seg::$43 } +Constantified RValue (struct SplineVector32) spline_16seg::p ← (struct SplineVector32){ (signed dword~) spline_16seg::$44, (signed dword~) spline_16seg::$45 } +Constantified RValue (struct SplineVector32) spline_16seg::i ← (struct SplineVector32){ (signed dword~) spline_16seg::$46, (signed dword~) spline_16seg::$47 } +Constantified RValue *((const struct SplineVector16*) SPLINE_16SEG + (number~) spline_16seg::$50) ← (struct SplineVector16){ (signed word~) spline_16seg::$34, (signed word~) spline_16seg::$37 } +Constantified RValue *((const struct SplineVector16*) SPLINE_8SEG + (byte~) spline_8seg::$51) ← (struct SplineVector16){ (signed word~) spline_8seg::$42, (signed word~) spline_8seg::$45 } +Constantified RValue (struct SplineVector32) spline_8seg::p ← (struct SplineVector32){ (signed dword~) spline_8seg::$46, (signed dword~) spline_8seg::$47 } +Constantified RValue (struct SplineVector32) spline_8seg::i ← (struct SplineVector32){ (signed dword~) spline_8seg::$48, (signed dword~) spline_8seg::$49 } +Constantified RValue *((const struct SplineVector16*) SPLINE_8SEG + (number~) spline_8seg::$52) ← (struct SplineVector16){ (signed word~) spline_8seg::$36, (signed word~) spline_8seg::$39 } +Constantified RValue *((const struct SplineVector16*) SPLINE_8SEG + (byte~) spline_8segB::$31) ← (struct SplineVector16){ (signed word)(number~) spline_8segB::$23, (signed word)(number~) spline_8segB::$25 } +Constantified RValue (struct SplineVector16) spline_8segB::p ← (struct SplineVector16){ (signed word~) spline_8segB::$26, (signed word~) spline_8segB::$27 } +Constantified RValue (struct SplineVector16) spline_8segB::i ← (struct SplineVector16){ (signed word~) spline_8segB::$28, (signed word~) spline_8segB::$29 } +Constantified RValue *((const struct SplineVector16*) SPLINE_8SEG + (number~) spline_8segB::$32) ← (struct SplineVector16){ (signed word)(number~) spline_8segB::$19, (signed word)(number~) spline_8segB::$21 } +Constantified RValue (struct SplineVector16) show_letter::to ← (struct SplineVector16){ (signed word)(number~) show_letter::$0, (signed word)(number~) show_letter::$1 } +Constantified RValue (struct SplineVector16) show_letter::to ← (struct SplineVector16){ (signed word)(number~) show_letter::$3, (signed word)(number~) show_letter::$4 } +Constantified RValue (struct SplineVector16) show_letter::via ← (struct SplineVector16){ (signed word)(number~) show_letter::$5, (signed word)(number~) show_letter::$6 } +Constantified RValue (struct SplineVector16) show_letter::via ← (struct SplineVector16){ (signed word)(number~) show_letter::$8, (signed word)(number~) show_letter::$9 } Created struct value member variable (signed word) spline_16seg::p0_x Created struct value member variable (signed word) spline_16seg::p0_y Converted struct value to member variables (struct SplineVector16) spline_16seg::p0 @@ -131,92 +147,92 @@ Converted procedure struct value parameter to member unwinding (void()) spline_1 Converted procedure struct value parameter to member unwinding (void()) spline_8seg((signed word) spline_8seg::p0_x , (signed word) spline_8seg::p0_y , (signed word) spline_8seg::p1_x , (signed word) spline_8seg::p1_y , (signed word) spline_8seg::p2_x , (signed word) spline_8seg::p2_y) Converted procedure struct value parameter to member unwinding (void()) spline_8segB((signed word) spline_8segB::p0_x , (signed word) spline_8segB::p0_y , (signed word) spline_8segB::p1_x , (signed word) spline_8segB::p1_y , (signed word) spline_8segB::p2_x , (signed word) spline_8segB::p2_y) Converted procedure struct value parameter to member unwinding (struct SplineVector16()) rotate((signed word) rotate::vector_x , (signed word) rotate::vector_y , (byte) rotate::angle) -Adding struct value list initializer (signed word) spline_16seg::a_x ← (number~) spline_16seg::$2 -Adding struct value list initializer (signed word) spline_16seg::a_y ← (number~) spline_16seg::$5 -Adding struct value list initializer (signed word) spline_16seg::b_x ← (number~) spline_16seg::$7 -Adding struct value list initializer (signed word) spline_16seg::b_y ← (number~) spline_16seg::$9 -Adding struct value list initializer (signed dword) spline_16seg::i_x ← (number~) spline_16seg::$15 -Adding struct value list initializer (signed dword) spline_16seg::i_y ← (number~) spline_16seg::$21 -Adding struct value list initializer (signed dword) spline_16seg::j_x ← (number~) spline_16seg::$24 -Adding struct value list initializer (signed dword) spline_16seg::j_y ← (number~) spline_16seg::$27 -Adding struct value list initializer (signed dword) spline_16seg::p_x ← (number~) spline_16seg::$29 -Adding struct value list initializer (signed dword) spline_16seg::p_y ← (number~) spline_16seg::$31 -Adding struct value list initializer *((signed word*~) spline_16seg::$51 + (byte~) spline_16seg::$49) ← (signed word~) spline_16seg::$40 -Adding struct value list initializer *((signed word*~) spline_16seg::$52 + (byte~) spline_16seg::$49) ← (signed word~) spline_16seg::$43 -Adding struct value list initializer (signed dword) spline_16seg::p_x ← (signed dword~) spline_16seg::$44 -Adding struct value list initializer (signed dword) spline_16seg::p_y ← (signed dword~) spline_16seg::$45 -Adding struct value list initializer (signed dword) spline_16seg::i_x ← (signed dword~) spline_16seg::$46 -Adding struct value list initializer (signed dword) spline_16seg::i_y ← (signed dword~) spline_16seg::$47 -Adding struct value list initializer *((signed word*~) spline_16seg::$53 + (number~) spline_16seg::$50) ← (signed word~) spline_16seg::$34 -Adding struct value list initializer *((signed word*~) spline_16seg::$54 + (number~) spline_16seg::$50) ← (signed word~) spline_16seg::$37 -Adding struct value list initializer (signed word) spline_8seg::a_x ← (number~) spline_8seg::$2 -Adding struct value list initializer (signed word) spline_8seg::a_y ← (number~) spline_8seg::$5 -Adding struct value list initializer (signed word) spline_8seg::b_x ← (number~) spline_8seg::$7 -Adding struct value list initializer (signed word) spline_8seg::b_y ← (number~) spline_8seg::$9 -Adding struct value list initializer (signed dword) spline_8seg::i_x ← (number~) spline_8seg::$16 -Adding struct value list initializer (signed dword) spline_8seg::i_y ← (number~) spline_8seg::$23 -Adding struct value list initializer (signed dword) spline_8seg::j_x ← (number~) spline_8seg::$26 -Adding struct value list initializer (signed dword) spline_8seg::j_y ← (number~) spline_8seg::$29 -Adding struct value list initializer (signed dword) spline_8seg::p_x ← (number~) spline_8seg::$31 -Adding struct value list initializer (signed dword) spline_8seg::p_y ← (number~) spline_8seg::$33 -Adding struct value list initializer *((signed word*~) spline_8seg::$53 + (byte~) spline_8seg::$51) ← (signed word~) spline_8seg::$42 -Adding struct value list initializer *((signed word*~) spline_8seg::$54 + (byte~) spline_8seg::$51) ← (signed word~) spline_8seg::$45 -Adding struct value list initializer (signed dword) spline_8seg::p_x ← (signed dword~) spline_8seg::$46 -Adding struct value list initializer (signed dword) spline_8seg::p_y ← (signed dword~) spline_8seg::$47 -Adding struct value list initializer (signed dword) spline_8seg::i_x ← (signed dword~) spline_8seg::$48 -Adding struct value list initializer (signed dword) spline_8seg::i_y ← (signed dword~) spline_8seg::$49 -Adding struct value list initializer *((signed word*~) spline_8seg::$55 + (number~) spline_8seg::$52) ← (signed word~) spline_8seg::$36 -Adding struct value list initializer *((signed word*~) spline_8seg::$56 + (number~) spline_8seg::$52) ← (signed word~) spline_8seg::$39 -Adding struct value list initializer (signed word) spline_8segB::a_x ← (number~) spline_8segB::$2 -Adding struct value list initializer (signed word) spline_8segB::a_y ← (number~) spline_8segB::$5 -Adding struct value list initializer (signed word) spline_8segB::b_x ← (number~) spline_8segB::$7 -Adding struct value list initializer (signed word) spline_8segB::b_y ← (number~) spline_8segB::$9 -Adding struct value list initializer (signed word) spline_8segB::i_x ← (number~) spline_8segB::$11 -Adding struct value list initializer (signed word) spline_8segB::i_y ← (number~) spline_8segB::$13 -Adding struct value list initializer (signed word) spline_8segB::j_x ← (number~) spline_8segB::$14 -Adding struct value list initializer (signed word) spline_8segB::j_y ← (number~) spline_8segB::$15 -Adding struct value list initializer (signed word) spline_8segB::p_x ← (number~) spline_8segB::$16 -Adding struct value list initializer (signed word) spline_8segB::p_y ← (number~) spline_8segB::$17 -Adding struct value list initializer *((signed word*~) spline_8segB::$33 + (byte~) spline_8segB::$31) ← (number~) spline_8segB::$23 -Adding struct value list initializer *((signed word*~) spline_8segB::$34 + (byte~) spline_8segB::$31) ← (number~) spline_8segB::$25 -Adding struct value list initializer (signed word) spline_8segB::p_x ← (signed word~) spline_8segB::$26 -Adding struct value list initializer (signed word) spline_8segB::p_y ← (signed word~) spline_8segB::$27 -Adding struct value list initializer (signed word) spline_8segB::i_x ← (signed word~) spline_8segB::$28 -Adding struct value list initializer (signed word) spline_8segB::i_y ← (signed word~) spline_8segB::$29 -Adding struct value list initializer *((signed word*~) spline_8segB::$35 + (number~) spline_8segB::$32) ← (number~) spline_8segB::$19 -Adding struct value list initializer *((signed word*~) spline_8segB::$36 + (number~) spline_8segB::$32) ← (number~) spline_8segB::$21 +Adding struct value member variable copy (signed word) spline_16seg::a_x ← (number~) spline_16seg::$2 +Adding struct value member variable copy (signed word) spline_16seg::a_y ← (number~) spline_16seg::$5 +Adding struct value member variable copy (signed word) spline_16seg::b_x ← (number~) spline_16seg::$7 +Adding struct value member variable copy (signed word) spline_16seg::b_y ← (number~) spline_16seg::$9 +Adding struct value member variable copy (signed dword) spline_16seg::i_x ← (number~) spline_16seg::$15 +Adding struct value member variable copy (signed dword) spline_16seg::i_y ← (number~) spline_16seg::$21 +Adding struct value member variable copy (signed dword) spline_16seg::j_x ← (number~) spline_16seg::$24 +Adding struct value member variable copy (signed dword) spline_16seg::j_y ← (number~) spline_16seg::$27 +Adding struct value member variable copy (signed dword) spline_16seg::p_x ← (number~) spline_16seg::$29 +Adding struct value member variable copy (signed dword) spline_16seg::p_y ← (number~) spline_16seg::$31 +Adding struct value member variable copy *((signed word*~) spline_16seg::$51 + (byte~) spline_16seg::$49) ← (signed word~) spline_16seg::$40 +Adding struct value member variable copy *((signed word*~) spline_16seg::$52 + (byte~) spline_16seg::$49) ← (signed word~) spline_16seg::$43 +Adding struct value member variable copy (signed dword) spline_16seg::p_x ← (signed dword~) spline_16seg::$44 +Adding struct value member variable copy (signed dword) spline_16seg::p_y ← (signed dword~) spline_16seg::$45 +Adding struct value member variable copy (signed dword) spline_16seg::i_x ← (signed dword~) spline_16seg::$46 +Adding struct value member variable copy (signed dword) spline_16seg::i_y ← (signed dword~) spline_16seg::$47 +Adding struct value member variable copy *((signed word*~) spline_16seg::$53 + (number~) spline_16seg::$50) ← (signed word~) spline_16seg::$34 +Adding struct value member variable copy *((signed word*~) spline_16seg::$54 + (number~) spline_16seg::$50) ← (signed word~) spline_16seg::$37 +Adding struct value member variable copy (signed word) spline_8seg::a_x ← (number~) spline_8seg::$2 +Adding struct value member variable copy (signed word) spline_8seg::a_y ← (number~) spline_8seg::$5 +Adding struct value member variable copy (signed word) spline_8seg::b_x ← (number~) spline_8seg::$7 +Adding struct value member variable copy (signed word) spline_8seg::b_y ← (number~) spline_8seg::$9 +Adding struct value member variable copy (signed dword) spline_8seg::i_x ← (number~) spline_8seg::$16 +Adding struct value member variable copy (signed dword) spline_8seg::i_y ← (number~) spline_8seg::$23 +Adding struct value member variable copy (signed dword) spline_8seg::j_x ← (number~) spline_8seg::$26 +Adding struct value member variable copy (signed dword) spline_8seg::j_y ← (number~) spline_8seg::$29 +Adding struct value member variable copy (signed dword) spline_8seg::p_x ← (number~) spline_8seg::$31 +Adding struct value member variable copy (signed dword) spline_8seg::p_y ← (number~) spline_8seg::$33 +Adding struct value member variable copy *((signed word*~) spline_8seg::$53 + (byte~) spline_8seg::$51) ← (signed word~) spline_8seg::$42 +Adding struct value member variable copy *((signed word*~) spline_8seg::$54 + (byte~) spline_8seg::$51) ← (signed word~) spline_8seg::$45 +Adding struct value member variable copy (signed dword) spline_8seg::p_x ← (signed dword~) spline_8seg::$46 +Adding struct value member variable copy (signed dword) spline_8seg::p_y ← (signed dword~) spline_8seg::$47 +Adding struct value member variable copy (signed dword) spline_8seg::i_x ← (signed dword~) spline_8seg::$48 +Adding struct value member variable copy (signed dword) spline_8seg::i_y ← (signed dword~) spline_8seg::$49 +Adding struct value member variable copy *((signed word*~) spline_8seg::$55 + (number~) spline_8seg::$52) ← (signed word~) spline_8seg::$36 +Adding struct value member variable copy *((signed word*~) spline_8seg::$56 + (number~) spline_8seg::$52) ← (signed word~) spline_8seg::$39 +Adding struct value member variable copy (signed word) spline_8segB::a_x ← (number~) spline_8segB::$2 +Adding struct value member variable copy (signed word) spline_8segB::a_y ← (number~) spline_8segB::$5 +Adding struct value member variable copy (signed word) spline_8segB::b_x ← (number~) spline_8segB::$7 +Adding struct value member variable copy (signed word) spline_8segB::b_y ← (number~) spline_8segB::$9 +Adding struct value member variable copy (signed word) spline_8segB::i_x ← (number~) spline_8segB::$11 +Adding struct value member variable copy (signed word) spline_8segB::i_y ← (number~) spline_8segB::$13 +Adding struct value member variable copy (signed word) spline_8segB::j_x ← (number~) spline_8segB::$14 +Adding struct value member variable copy (signed word) spline_8segB::j_y ← (number~) spline_8segB::$15 +Adding struct value member variable copy (signed word) spline_8segB::p_x ← (number~) spline_8segB::$16 +Adding struct value member variable copy (signed word) spline_8segB::p_y ← (number~) spline_8segB::$17 +Adding struct value member variable copy *((signed word*~) spline_8segB::$33 + (byte~) spline_8segB::$31) ← (signed word)(number~) spline_8segB::$23 +Adding struct value member variable copy *((signed word*~) spline_8segB::$34 + (byte~) spline_8segB::$31) ← (signed word)(number~) spline_8segB::$25 +Adding struct value member variable copy (signed word) spline_8segB::p_x ← (signed word~) spline_8segB::$26 +Adding struct value member variable copy (signed word) spline_8segB::p_y ← (signed word~) spline_8segB::$27 +Adding struct value member variable copy (signed word) spline_8segB::i_x ← (signed word~) spline_8segB::$28 +Adding struct value member variable copy (signed word) spline_8segB::i_y ← (signed word~) spline_8segB::$29 +Adding struct value member variable copy *((signed word*~) spline_8segB::$35 + (number~) spline_8segB::$32) ← (signed word)(number~) spline_8segB::$19 +Adding struct value member variable copy *((signed word*~) spline_8segB::$36 + (number~) spline_8segB::$32) ← (signed word)(number~) spline_8segB::$21 Adding struct value member variable copy (signed word) show_letter::current_x ← (signed word) 0 Adding struct value member variable copy (signed word) show_letter::current_y ← (signed word) 0 -Adding struct value list initializer (signed word) show_letter::to_x ← *((const struct Segment*) letter_c + (byte~) show_letter::$20).to.x -Adding struct value list initializer (signed word) show_letter::to_y ← *((const struct Segment*) letter_c + (byte~) show_letter::$20).to.y -Adding struct value list initializer (signed word) show_letter::to_x ← (number~) show_letter::$0 -Adding struct value list initializer (signed word) show_letter::to_y ← (number~) show_letter::$1 +Adding struct value member variable copy (signed word) show_letter::to_x ← *((const struct Segment*) letter_c + (byte~) show_letter::$20).to.x +Adding struct value member variable copy (signed word) show_letter::to_y ← *((const struct Segment*) letter_c + (byte~) show_letter::$20).to.y +Adding struct value member variable copy (signed word) show_letter::to_x ← (signed word)(number~) show_letter::$0 +Adding struct value member variable copy (signed word) show_letter::to_y ← (signed word)(number~) show_letter::$1 Converted procedure call LValue to member unwinding { (signed word~) show_letter::$2_x, (signed word~) show_letter::$2_y } ← call rotate (struct SplineVector16) show_letter::to (byte) show_letter::angle Converted procedure struct value parameter to member unwinding in call { (signed word~) show_letter::$2_x, (signed word~) show_letter::$2_y } ← call rotate (signed word) show_letter::to_x (signed word) show_letter::to_y (byte) show_letter::angle Adding struct value member variable copy (signed word) show_letter::to_x ← (signed word~) show_letter::$2_x Adding struct value member variable copy (signed word) show_letter::to_y ← (signed word~) show_letter::$2_y -Adding struct value list initializer (signed word) show_letter::to_x ← (number~) show_letter::$3 -Adding struct value list initializer (signed word) show_letter::to_y ← (number~) show_letter::$4 -Adding struct value list initializer (signed word) show_letter::via_x ← *((const struct Segment*) letter_c + (byte~) show_letter::$21).via.x -Adding struct value list initializer (signed word) show_letter::via_y ← *((const struct Segment*) letter_c + (byte~) show_letter::$21).via.y -Adding struct value list initializer (signed word) show_letter::via_x ← (number~) show_letter::$5 -Adding struct value list initializer (signed word) show_letter::via_y ← (number~) show_letter::$6 +Adding struct value member variable copy (signed word) show_letter::to_x ← (signed word)(number~) show_letter::$3 +Adding struct value member variable copy (signed word) show_letter::to_y ← (signed word)(number~) show_letter::$4 +Adding struct value member variable copy (signed word) show_letter::via_x ← *((const struct Segment*) letter_c + (byte~) show_letter::$21).via.x +Adding struct value member variable copy (signed word) show_letter::via_y ← *((const struct Segment*) letter_c + (byte~) show_letter::$21).via.y +Adding struct value member variable copy (signed word) show_letter::via_x ← (signed word)(number~) show_letter::$5 +Adding struct value member variable copy (signed word) show_letter::via_y ← (signed word)(number~) show_letter::$6 Converted procedure call LValue to member unwinding { (signed word~) show_letter::$7_x, (signed word~) show_letter::$7_y } ← call rotate (struct SplineVector16) show_letter::via (byte) show_letter::angle Converted procedure struct value parameter to member unwinding in call { (signed word~) show_letter::$7_x, (signed word~) show_letter::$7_y } ← call rotate (signed word) show_letter::via_x (signed word) show_letter::via_y (byte) show_letter::angle Adding struct value member variable copy (signed word) show_letter::via_x ← (signed word~) show_letter::$7_x Adding struct value member variable copy (signed word) show_letter::via_y ← (signed word~) show_letter::$7_y -Adding struct value list initializer (signed word) show_letter::via_x ← (number~) show_letter::$8 -Adding struct value list initializer (signed word) show_letter::via_y ← (number~) show_letter::$9 -Adding struct value list initializer (byte) show_letter::segment_type ← *((const struct Segment*) letter_c + (byte~) show_letter::$22).type -Adding struct value list initializer (struct SplineVector16) show_letter::segment_to ← (struct SplineVector16) show_letter::to -Adding struct value list initializer (struct SplineVector16) show_letter::segment_via ← (struct SplineVector16) show_letter::via +Adding struct value member variable copy (signed word) show_letter::via_x ← (signed word)(number~) show_letter::$8 +Adding struct value member variable copy (signed word) show_letter::via_y ← (signed word)(number~) show_letter::$9 +Adding struct value member variable copy (byte) show_letter::segment_type ← *((const struct Segment*) letter_c + (byte~) show_letter::$22).type +Adding struct value member variable copy (struct SplineVector16) show_letter::segment_to ← (struct SplineVector16) show_letter::to +Adding struct value member variable copy (struct SplineVector16) show_letter::segment_via ← (struct SplineVector16) show_letter::via Converted procedure struct value parameter to member unwinding in call (void~) show_letter::$17 ← call spline_8segB (signed word) show_letter::current_x (signed word) show_letter::current_y (struct Segment) show_letter::segment.via (struct Segment) show_letter::segment.to Adding struct value member variable copy (signed word) bitmap_plot_spline_8seg::current_x ← *((signed word*~) bitmap_plot_spline_8seg::$10 + (number~) bitmap_plot_spline_8seg::$6) Adding struct value member variable copy (signed word) bitmap_plot_spline_8seg::current_y ← *((signed word*~) bitmap_plot_spline_8seg::$11 + (number~) bitmap_plot_spline_8seg::$6) Adding struct value member variable copy (signed word) bitmap_plot_spline_8seg::current_x ← *((signed word*~) bitmap_plot_spline_8seg::$12 + (byte~) bitmap_plot_spline_8seg::$9) Adding struct value member variable copy (signed word) bitmap_plot_spline_8seg::current_y ← *((signed word*~) bitmap_plot_spline_8seg::$13 + (byte~) bitmap_plot_spline_8seg::$9) -Adding struct value list initializer (signed word) rotate::rotated_x ← (signed word~) rotate::$16 -Adding struct value list initializer (signed word) rotate::rotated_y ← (signed word~) rotate::$19 +Adding struct value member variable copy (signed word) rotate::rotated_x ← (signed word~) rotate::$16 +Adding struct value member variable copy (signed word) rotate::rotated_y ← (signed word~) rotate::$19 Adding struct value member variable copy (signed word) rotate::return_x ← (signed word) rotate::rotated_x Adding struct value member variable copy (signed word) rotate::return_y ← (signed word) rotate::rotated_y Adding struct value member variable copy (signed word) rotate::return_x ← (signed word) rotate::return_x @@ -547,9 +563,9 @@ spline_8segB::@1: scope:[spline_8segB] from spline_8segB spline_8segB::@1 (number~) spline_8segB::$25 ← (number~) spline_8segB::$24 / (number) $40 (byte~) spline_8segB::$31 ← (byte) spline_8segB::n#2 * (const byte) SIZEOF_STRUCT_SPLINEVECTOR16 (signed word*~) spline_8segB::$33 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X - *((signed word*~) spline_8segB::$33 + (byte~) spline_8segB::$31) ← (number~) spline_8segB::$23 + *((signed word*~) spline_8segB::$33 + (byte~) spline_8segB::$31) ← (signed word)(number~) spline_8segB::$23 (signed word*~) spline_8segB::$34 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y - *((signed word*~) spline_8segB::$34 + (byte~) spline_8segB::$31) ← (number~) spline_8segB::$25 + *((signed word*~) spline_8segB::$34 + (byte~) spline_8segB::$31) ← (signed word)(number~) spline_8segB::$25 (signed word~) spline_8segB::$26 ← (signed word) spline_8segB::p_x#2 + (signed word) spline_8segB::i_x#2 (signed word~) spline_8segB::$27 ← (signed word) spline_8segB::p_y#2 + (signed word) spline_8segB::i_y#2 (signed word) spline_8segB::p_x#1 ← (signed word~) spline_8segB::$26 @@ -571,9 +587,9 @@ spline_8segB::@2: scope:[spline_8segB] from spline_8segB::@1 (number~) spline_8segB::$21 ← (number~) spline_8segB::$20 / (number) $40 (number~) spline_8segB::$32 ← (number) 8 * (const byte) SIZEOF_STRUCT_SPLINEVECTOR16 (signed word*~) spline_8segB::$35 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X - *((signed word*~) spline_8segB::$35 + (number~) spline_8segB::$32) ← (number~) spline_8segB::$19 + *((signed word*~) spline_8segB::$35 + (number~) spline_8segB::$32) ← (signed word)(number~) spline_8segB::$19 (signed word*~) spline_8segB::$36 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y - *((signed word*~) spline_8segB::$36 + (number~) spline_8segB::$32) ← (number~) spline_8segB::$21 + *((signed word*~) spline_8segB::$36 + (number~) spline_8segB::$32) ← (signed word)(number~) spline_8segB::$21 to:spline_8segB::@return spline_8segB::@return: scope:[spline_8segB] from spline_8segB::@2 return @@ -1408,8 +1424,8 @@ show_letter::@1: scope:[show_letter] from show_letter show_letter::@5 (signed word) show_letter::to_y#0 ← *((signed word*~) show_letter::$29 + (byte~) show_letter::$20) (number~) show_letter::$0 ← (signed word) show_letter::to_x#0 - (number) $32 (number~) show_letter::$1 ← (signed word) show_letter::to_y#0 - (number) $96 - (signed word) show_letter::to_x#1 ← (number~) show_letter::$0 - (signed word) show_letter::to_y#1 ← (number~) show_letter::$1 + (signed word) show_letter::to_x#1 ← (signed word)(number~) show_letter::$0 + (signed word) show_letter::to_y#1 ← (signed word)(number~) show_letter::$1 (signed word) rotate::vector_x#0 ← (signed word) show_letter::to_x#1 (signed word) rotate::vector_y#0 ← (signed word) show_letter::to_y#1 (byte) rotate::angle#0 ← (byte) show_letter::angle#1 @@ -1430,8 +1446,8 @@ show_letter::@11: scope:[show_letter] from show_letter::@1 (signed word) show_letter::to_y#2 ← (signed word~) show_letter::$2_y (number~) show_letter::$3 ← (signed word) show_letter::to_x#2 + (number) $64 (number~) show_letter::$4 ← (signed word) show_letter::to_y#2 + (number) $64 - (signed word) show_letter::to_x#3 ← (number~) show_letter::$3 - (signed word) show_letter::to_y#3 ← (number~) show_letter::$4 + (signed word) show_letter::to_x#3 ← (signed word)(number~) show_letter::$3 + (signed word) show_letter::to_y#3 ← (signed word)(number~) show_letter::$4 (byte~) show_letter::$21 ← (byte) show_letter::i#3 * (const byte) SIZEOF_STRUCT_SEGMENT (struct SplineVector16*~) show_letter::$25 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA (signed word*~) show_letter::$30 ← (signed word*)(struct SplineVector16*~) show_letter::$25 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X @@ -1441,8 +1457,8 @@ show_letter::@11: scope:[show_letter] from show_letter::@1 (signed word) show_letter::via_y#0 ← *((signed word*~) show_letter::$31 + (byte~) show_letter::$21) (number~) show_letter::$5 ← (signed word) show_letter::via_x#0 - (number) $32 (number~) show_letter::$6 ← (signed word) show_letter::via_y#0 - (number) $96 - (signed word) show_letter::via_x#1 ← (number~) show_letter::$5 - (signed word) show_letter::via_y#1 ← (number~) show_letter::$6 + (signed word) show_letter::via_x#1 ← (signed word)(number~) show_letter::$5 + (signed word) show_letter::via_y#1 ← (signed word)(number~) show_letter::$6 (signed word) rotate::vector_x#1 ← (signed word) show_letter::via_x#1 (signed word) rotate::vector_y#1 ← (signed word) show_letter::via_y#1 (byte) rotate::angle#1 ← (byte) show_letter::angle#2 @@ -1465,8 +1481,8 @@ show_letter::@12: scope:[show_letter] from show_letter::@11 (signed word) show_letter::via_y#2 ← (signed word~) show_letter::$7_y (number~) show_letter::$8 ← (signed word) show_letter::via_x#2 + (number) $64 (number~) show_letter::$9 ← (signed word) show_letter::via_y#2 + (number) $64 - (signed word) show_letter::via_x#3 ← (number~) show_letter::$8 - (signed word) show_letter::via_y#3 ← (number~) show_letter::$9 + (signed word) show_letter::via_x#3 ← (signed word)(number~) show_letter::$8 + (signed word) show_letter::via_y#3 ← (signed word)(number~) show_letter::$9 (byte~) show_letter::$22 ← (byte) show_letter::i#4 * (const byte) SIZEOF_STRUCT_SEGMENT (byte*~) show_letter::$27 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TYPE (byte) show_letter::segment_type#0 ← *((byte*~) show_letter::$27 + (byte~) show_letter::$22) @@ -3397,8 +3413,6 @@ Alias (byte*) bitmap_screen#23 = (byte*) bitmap_screen#26 (byte*) bitmap_screen# Alias (byte*) bitmap_gfx#24 = (byte*) bitmap_gfx#27 (byte*) bitmap_gfx#31 Alias (byte*) bitmap_gfx#14 = (byte*) bitmap_gfx#21 (byte*) bitmap_gfx#9 (byte*) bitmap_gfx#4 Alias (byte*) bitmap_screen#14 = (byte*) bitmap_screen#20 (byte*) bitmap_screen#9 (byte*) bitmap_screen#4 -Alias (signed word) show_letter::to_x#1 = (signed word~) show_letter::$0 -Alias (signed word) show_letter::to_y#1 = (signed word~) show_letter::$1 Alias (signed word) rotate::return_x#0 = (signed word) rotate::return_x#4 Alias (signed word) rotate::return_y#0 = (signed word) rotate::return_y#4 Alias (byte) show_letter::i#10 = (byte) show_letter::i#3 (byte) show_letter::i#2 (byte) show_letter::i#4 (byte) show_letter::i#8 (byte) show_letter::i#12 (byte) show_letter::i#11 (byte) show_letter::i#9 (byte) show_letter::i#6 (byte) show_letter::i#7 @@ -3407,16 +3421,14 @@ Alias (signed word) show_letter::current_x#4 = (signed word) show_letter::curren Alias (signed word) show_letter::current_y#4 = (signed word) show_letter::current_y#8 (signed word) show_letter::current_y#9 (signed word) show_letter::current_y#7 (signed word) show_letter::current_y#6 (signed word) show_letter::current_y#5 Alias (signed word) show_letter::to_x#2 = (signed word~) show_letter::$2_x Alias (signed word) show_letter::to_y#2 = (signed word~) show_letter::$2_y -Alias (signed word) show_letter::segment_to_x#0 = (signed word) show_letter::to_x#3 (signed word~) show_letter::$3 (signed word) show_letter::to_x#4 (signed word) show_letter::segment_to_x#1 (signed word) show_letter::current_x#1 (signed word) show_letter::segment_to_x#6 (signed word) show_letter::segment_to_x#2 (signed word) show_letter::segment_to_x#7 (signed word) show_letter::segment_to_x#3 (signed word) show_letter::current_x#2 (signed word) show_letter::segment_to_x#4 (signed word) show_letter::segment_to_x#5 (signed word) show_letter::current_x#3 -Alias (signed word) show_letter::segment_to_y#0 = (signed word) show_letter::to_y#3 (signed word~) show_letter::$4 (signed word) show_letter::to_y#4 (signed word) show_letter::segment_to_y#1 (signed word) show_letter::current_y#1 (signed word) show_letter::segment_to_y#6 (signed word) show_letter::segment_to_y#2 (signed word) show_letter::segment_to_y#7 (signed word) show_letter::segment_to_y#3 (signed word) show_letter::current_y#2 (signed word) show_letter::segment_to_y#4 (signed word) show_letter::segment_to_y#5 (signed word) show_letter::current_y#3 -Alias (signed word) show_letter::via_x#1 = (signed word~) show_letter::$5 -Alias (signed word) show_letter::via_y#1 = (signed word~) show_letter::$6 Alias (signed word) rotate::return_x#1 = (signed word) rotate::return_x#5 Alias (signed word) rotate::return_y#1 = (signed word) rotate::return_y#5 +Alias (signed word) show_letter::segment_to_x#0 = (signed word) show_letter::to_x#4 (signed word) show_letter::to_x#3 (signed word) show_letter::segment_to_x#1 (signed word) show_letter::current_x#1 (signed word) show_letter::segment_to_x#6 (signed word) show_letter::segment_to_x#2 (signed word) show_letter::segment_to_x#7 (signed word) show_letter::segment_to_x#3 (signed word) show_letter::current_x#2 (signed word) show_letter::segment_to_x#4 (signed word) show_letter::segment_to_x#5 (signed word) show_letter::current_x#3 +Alias (signed word) show_letter::segment_to_y#0 = (signed word) show_letter::to_y#4 (signed word) show_letter::to_y#3 (signed word) show_letter::segment_to_y#1 (signed word) show_letter::current_y#1 (signed word) show_letter::segment_to_y#6 (signed word) show_letter::segment_to_y#2 (signed word) show_letter::segment_to_y#7 (signed word) show_letter::segment_to_y#3 (signed word) show_letter::current_y#2 (signed word) show_letter::segment_to_y#4 (signed word) show_letter::segment_to_y#5 (signed word) show_letter::current_y#3 Alias (signed word) show_letter::via_x#2 = (signed word~) show_letter::$7_x Alias (signed word) show_letter::via_y#2 = (signed word~) show_letter::$7_y -Alias (signed word) show_letter::segment_via_x#0 = (signed word) show_letter::via_x#3 (signed word~) show_letter::$8 (signed word) show_letter::segment_via_x#2 (signed word) show_letter::segment_via_x#1 -Alias (signed word) show_letter::segment_via_y#0 = (signed word) show_letter::via_y#3 (signed word~) show_letter::$9 (signed word) show_letter::segment_via_y#2 (signed word) show_letter::segment_via_y#1 +Alias (signed word) show_letter::segment_via_x#0 = (signed word) show_letter::via_x#3 (signed word) show_letter::segment_via_x#2 (signed word) show_letter::segment_via_x#1 +Alias (signed word) show_letter::segment_via_y#0 = (signed word) show_letter::via_y#3 (signed word) show_letter::segment_via_y#2 (signed word) show_letter::segment_via_y#1 Alias (byte) show_letter::segment_type#0 = (byte) show_letter::segment_type#1 Alias (word) bitmap_line::x1#0 = (word~) show_letter::$12 Alias (word) bitmap_line::y1#0 = (word~) show_letter::$13 @@ -3685,8 +3697,8 @@ Simplifying expression containing zero bitmap_plot_spline_8seg::$11 in [543] (si Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused variable (void*) memset::return#2 and assignment [75] (void*) memset::return#2 ← (void*) memset::str#3 Eliminating unused variable (void*) memset::return#3 and assignment [77] (void*) memset::return#3 ← (void*) memset::str#3 -Eliminating unused variable (struct SplineVector16) rotate::return#0 and assignment [344] (struct SplineVector16) rotate::return#0 ← struct-unwound {(signed word) rotate::return_x#2, (signed word) rotate::return_y#2} -Eliminating unused variable (struct SplineVector16) rotate::return#1 and assignment [345] (struct SplineVector16) rotate::return#1 ← struct-unwound {(signed word) rotate::return_x#2, (signed word) rotate::return_y#2} +Eliminating unused variable (struct SplineVector16) rotate::return#0 and assignment [352] (struct SplineVector16) rotate::return#0 ← struct-unwound {(signed word) rotate::return_x#2, (signed word) rotate::return_y#2} +Eliminating unused variable (struct SplineVector16) rotate::return#1 and assignment [353] (struct SplineVector16) rotate::return#1 ← struct-unwound {(signed word) rotate::return_x#2, (signed word) rotate::return_y#2} Eliminating unused constant (const byte) bitmap_plot_spline_8seg::$6 Eliminating unused constant (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X Eliminating unused constant (const byte) OFFSET_STRUCT_SEGMENT_TYPE @@ -3706,10 +3718,22 @@ Adding number conversion cast (unumber) 9 in if((byte) bitmap_plot_spline_8seg:: Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (byte*) bitmap_plot::plotter#0 ← (byte*)(word~) bitmap_plot::$3 Successful SSA optimization Pass2InlineCast +Simplifying constant integer cast (signed word~) spline_8segB::$23 +Simplifying constant integer cast (signed word~) spline_8segB::$25 Simplifying constant integer cast 8 +Simplifying constant integer cast (signed word~) spline_8segB::$19 +Simplifying constant integer cast (signed word~) spline_8segB::$21 Simplifying constant integer cast 0 Simplifying constant integer cast 0 Simplifying constant integer cast $3d +Simplifying constant integer cast (signed word~) show_letter::$0 +Simplifying constant integer cast (signed word~) show_letter::$1 +Simplifying constant integer cast (signed word~) show_letter::$3 +Simplifying constant integer cast (signed word~) show_letter::$4 +Simplifying constant integer cast (signed word~) show_letter::$5 +Simplifying constant integer cast (signed word~) show_letter::$6 +Simplifying constant integer cast (signed word~) show_letter::$8 +Simplifying constant integer cast (signed word~) show_letter::$9 Simplifying constant integer cast $16 Simplifying constant integer cast 9 Successful SSA optimization PassNCastSimplification @@ -3721,10 +3745,18 @@ Finalized unsigned number type (byte) $16 Finalized unsigned number type (byte) 9 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (byte~) bitmap_init::$7 = (byte~) bitmap_init::$3 +Alias (signed word) show_letter::to_x#1 = (signed word~) show_letter::$0 +Alias (signed word) show_letter::to_y#1 = (signed word~) show_letter::$1 +Alias (signed word) show_letter::current_x#10 = (signed word~) show_letter::$3 +Alias (signed word) show_letter::current_y#10 = (signed word~) show_letter::$4 +Alias (signed word) show_letter::via_x#1 = (signed word~) show_letter::$5 +Alias (signed word) show_letter::via_y#1 = (signed word~) show_letter::$6 +Alias (signed word) show_letter::segment_via_x#0 = (signed word~) show_letter::$8 +Alias (signed word) show_letter::segment_via_y#0 = (signed word~) show_letter::$9 Alias (byte~) bitmap_plot_spline_8seg::$8 = (byte~) bitmap_plot_spline_8seg::$7 Successful SSA optimization Pass2AliasElimination Simple Condition (bool~) bitmap_line::$4 [96] if((word) bitmap_line::dx#0==(byte) 0) goto bitmap_line::@24 -Simple Condition (bool~) bitmap_line::$5 [342] if((word) bitmap_line::dy#0==(byte) 0) goto bitmap_line::@4 +Simple Condition (bool~) bitmap_line::$5 [350] if((word) bitmap_line::dy#0==(byte) 0) goto bitmap_line::@4 Successful SSA optimization Pass2ConditionalJumpSimplification Negating conditional jump and destination [96] if((word) bitmap_line::dx#0!=(byte) 0) goto bitmap_line::@1 Successful SSA optimization Pass2ConditionalJumpSequenceImprovement @@ -3732,7 +3764,7 @@ Constant right-side identified [207] (byte~) main::vicSelectGfxBank1_toDd001_$1 Constant right-side identified [211] (word~) main::toD0181_$1 ← (const word) main::toD0181_$0 & (word) $3fff Constant right-side identified [214] (byte~) main::toD0181_$5 ← > (const word) main::toD0181_$4 Constant right-side identified [234] (signed word*~) show_letter::$29 ← (signed word*)(const struct SplineVector16*) show_letter::$24 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y -Constant right-side identified [251] (signed word*~) show_letter::$31 ← (signed word*)(const struct SplineVector16*) show_letter::$26 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y +Constant right-side identified [255] (signed word*~) show_letter::$31 ← (signed word*)(const struct SplineVector16*) show_letter::$26 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) main::vicSelectGfxBank1_toDd001_$1 = >main::vicSelectGfxBank1_toDd001_$0 Constant (const word) main::toD0181_$1 = main::toD0181_$0&$3fff @@ -12549,7 +12581,7 @@ show_letter: { // to = rotate(to, angle) // [41] (signed word) show_letter::to_x#2 ← (signed word) rotate::return_x#0 // [42] (signed word) show_letter::to_y#2 ← (signed word) rotate::return_y#0 - // to.x + 100 + // to = { to.x + 100, to.y + 100} // [43] (signed word) show_letter::current_x#10 ← (signed word) show_letter::to_x#2 + (signed byte) $64 -- vwsz1=vwsz2_plus_vbsc1 lda.z to_x_1 clc @@ -12558,7 +12590,6 @@ show_letter: { lda.z to_x_1+1 adc #>$64 sta.z current_x_1+1 - // to.y + 100 // [44] (signed word) show_letter::current_y#10 ← (signed word) show_letter::to_y#2 + (signed byte) $64 -- vwsz1=vwsz2_plus_vbsc1 lda.z to_y_1 clc @@ -12622,7 +12653,7 @@ show_letter: { // via = rotate(via, angle) // [57] (signed word) show_letter::via_x#2 ← (signed word) rotate::return_x#1 // [58] (signed word) show_letter::via_y#2 ← (signed word) rotate::return_y#1 - // via.x + 100 + // via = { via.x + 100, via.y + 100} // [59] (signed word) show_letter::segment_via_x#0 ← (signed word) show_letter::via_x#2 + (signed byte) $64 -- vwsz1=vwsz1_plus_vbsc1 lda.z segment_via_x clc @@ -12631,7 +12662,6 @@ show_letter: { lda.z segment_via_x+1 adc #>$64 sta.z segment_via_x+1 - // via.y + 100 // [60] (signed word) show_letter::segment_via_y#0 ← (signed word) show_letter::via_y#2 + (signed byte) $64 -- vwsz1=vwsz1_plus_vbsc1 lda.z segment_via_y clc diff --git a/src/test/ref/declared-memory-var-4.asm b/src/test/ref/declared-memory-var-4.asm index e099aca92..a9eadb8d7 100644 --- a/src/test/ref/declared-memory-var-4.asm +++ b/src/test/ref/declared-memory-var-4.asm @@ -5,21 +5,22 @@ .pc = $80d "Program" .const OFFSET_STRUCT_FOO_THING2 = 1 .const OFFSET_STRUCT_FOO_THING3 = 2 - .label bar_thing3 = 2 __bbegin: lda #'a' - sta bar_thing1 + sta bar lda #'b' - sta bar_thing2 - lda #<__0 - sta.z bar_thing3 - lda #>__0 - sta.z bar_thing3+1 + sta bar+OFFSET_STRUCT_FOO_THING2 + ldy #$c +!: + lda __0-1,y + sta bar+OFFSET_STRUCT_FOO_THING3-1,y + dey + bne !- jsr main rts main: { .label SCREEN = $400 - .label barp = bar_thing1 + .label barp = bar lda barp sta SCREEN lda barp+OFFSET_STRUCT_FOO_THING2 @@ -37,5 +38,5 @@ main: { } __0: .text "qwe" .byte 0 - bar_thing1: .byte 0 - bar_thing2: .byte 0 + .fill 8, 0 + bar: .byte 0, 0 diff --git a/src/test/ref/declared-memory-var-4.cfg b/src/test/ref/declared-memory-var-4.cfg index 9da0fcac1..f88a54b49 100644 --- a/src/test/ref/declared-memory-var-4.cfg +++ b/src/test/ref/declared-memory-var-4.cfg @@ -1,7 +1,7 @@ @begin: scope:[] from - [0] (byte) bar_thing1 ← (byte) 'a' - [1] (byte) bar_thing2 ← (byte) 'b' - [2] (const byte*) bar_thing3 ← (const string) $0 + [0] *((byte*)&(struct foo) bar) ← (byte) 'a' + [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' + [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) to:@1 @1: scope:[] from @begin [3] phi() diff --git a/src/test/ref/declared-memory-var-4.log b/src/test/ref/declared-memory-var-4.log index a21d84a18..7a8824ac7 100644 --- a/src/test/ref/declared-memory-var-4.log +++ b/src/test/ref/declared-memory-var-4.log @@ -1,30 +1,29 @@ Fixing struct type size struct foo to 14 Fixing struct type size struct foo to 14 +Fixing struct type SIZE_OF struct foo to 14 +Fixing struct type SIZE_OF struct foo to 14 Setting inferred volatile on symbol affected by address-of (struct foo*) main::barp ← &(struct foo) bar -Created struct value member variable (byte) bar_thing1 -Created struct value member variable (byte) bar_thing2 -Created struct value member variable (const byte*) bar_thing3 -Converted struct value to member variables (struct foo) bar -Adding struct value list initializer (byte) bar_thing1 ← (byte) 'a' -Adding struct value list initializer (byte) bar_thing2 ← (byte) 'b' -Adding struct value list initializer (const byte*) bar_thing3 ← (string) "qwe" +Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a' +Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' +Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) Rewriting struct pointer member access *((struct foo*) main::barp).thing1 Rewriting struct pointer member access *((struct foo*) main::barp).thing2 Rewriting struct pointer member access *((struct foo*) main::barp).thing3 Identified constant variable (struct foo*) main::barp Culled Empty Block (label) main::@2 +Adding versioned struct unwinding for (struct foo) bar CONTROL FLOW GRAPH SSA @begin: scope:[] from - (byte) bar_thing1 ← (byte) 'a' - (byte) bar_thing2 ← (byte) 'b' - (const byte*) bar_thing3 ← (const string) $0 - (struct foo) bar ← struct-unwound {(byte) bar_thing1, (byte) bar_thing2, (const byte*) bar_thing3} + *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a' + *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' + *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) + (struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2), (byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3} to:@1 (void()) main() main: scope:[main] from @1 - (byte) main::i#0 ← (number) 0 + (byte) main::i#0 ← (byte) 0 (byte*~) main::$1 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING1 *((const byte*) main::SCREEN + (byte) main::i#0) ← *((byte*~) main::$1) (byte) main::i#1 ← ++ (byte) main::i#0 @@ -54,7 +53,7 @@ main::@return: scope:[main] from main::@1 @end: scope:[] from @2 SYMBOL TABLE SSA -(const string) $0 = (string) "qwe" +(const byte*) $0[(number) $c] = (string) "qwe" (label) @1 (label) @2 (label) @begin @@ -63,12 +62,9 @@ SYMBOL TABLE SSA (const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1 (const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2 (struct foo) bar loadstore -(byte) bar_thing1 loadstore -(byte) bar_thing2 loadstore -(const byte*) bar_thing3 loadstore (byte) foo::thing1 (byte) foo::thing2 -(const byte*) foo::thing3 = { fill( $c, 0) } +(const byte*) foo::thing3[(number) $c] = { fill( $c, 0) } (void()) main() (bool~) main::$0 (byte*~) main::$1 @@ -89,19 +85,11 @@ SYMBOL TABLE SSA (byte) main::j#1 (byte) main::j#2 -Adding number conversion cast (unumber) 0 in (byte) main::i#0 ← (number) 0 -Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast (byte) main::i#0 ← (unumber)(number) 0 -Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 -Simplifying constant integer cast 0 Successful SSA optimization PassNCastSimplification -Finalized unsigned number type (byte) 0 -Successful SSA optimization PassNFinalizeNumberTypeConversions Simple Condition (bool~) main::$0 [18] if((byte) main::j#1!=rangelast(0,$b)) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification -Rewriting struct address-of to first member &(struct foo) bar -Successful SSA optimization PassNStructAddressOfRewriting +Removing C-classic struct-unwound assignment [3] (struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2), (byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3} Constant right-side identified [5] (byte*~) main::$1 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING1 Constant right-side identified [8] (byte*~) main::$2 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING2 Constant right-side identified [13] (byte*~) main::$3 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING3 @@ -115,9 +103,9 @@ Successful SSA optimization Pass2ConstantIdentification Resolved ranged next value [16] main::j#1 ← ++ main::j#2 to ++ Resolved ranged comparison value [18] if(main::j#1!=rangelast(0,$b)) goto main::@1 to (number) $c Simplifying expression containing zero (byte*)main::barp in +Simplifying expression containing zero (byte*)&bar in [0] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a' Simplifying expression containing zero main::SCREEN in [6] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((const byte*) main::$1) Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable (struct foo) bar and assignment [3] (struct foo) bar ← struct-unwound {(byte) bar_thing1, (byte) bar_thing2, (const byte*) bar_thing3} Eliminating unused constant (const byte) OFFSET_STRUCT_FOO_THING1 Successful SSA optimization PassNEliminateUnusedVars Adding number conversion cast (unumber) $c in if((byte) main::j#1!=(number) $c) goto main::@1 @@ -171,9 +159,9 @@ Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @begin: scope:[] from - [0] (byte) bar_thing1 ← (byte) 'a' - [1] (byte) bar_thing2 ← (byte) 'b' - [2] (const byte*) bar_thing3 ← (const string) $0 + [0] *((byte*)&(struct foo) bar) ← (byte) 'a' + [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' + [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) to:@1 @1: scope:[] from @begin [3] phi() @@ -201,9 +189,7 @@ main::@return: scope:[main] from main::@1 VARIABLE REGISTER WEIGHTS -(byte) bar_thing1 loadstore 20.0 -(byte) bar_thing2 loadstore 20.0 -(const byte*) bar_thing3 loadstore 20.0 +(struct foo) bar loadstore (byte) foo::thing1 (byte) foo::thing2 (void()) main() @@ -217,20 +203,14 @@ VARIABLE REGISTER WEIGHTS Initial phi equivalence classes [ main::j#2 main::j#1 ] [ main::i#4 main::i#3 ] -Added variable bar_thing1 to live range equivalence class [ bar_thing1 ] -Added variable bar_thing2 to live range equivalence class [ bar_thing2 ] -Added variable bar_thing3 to live range equivalence class [ bar_thing3 ] +Added variable bar to live range equivalence class [ bar ] Complete equivalence classes [ main::j#2 main::j#1 ] [ main::i#4 main::i#3 ] -[ bar_thing1 ] -[ bar_thing2 ] -[ bar_thing3 ] +[ bar ] Allocated zp[1]:2 [ main::j#2 main::j#1 ] Allocated zp[1]:3 [ main::i#4 main::i#3 ] -Allocated mem[1] [ bar_thing1 ] -Allocated mem[1] [ bar_thing2 ] -Allocated zp[2]:4 [ bar_thing3 ] +Allocated mem[14] [ bar ] INITIAL ASM Target platform is c64basic / MOS6502X @@ -244,20 +224,21 @@ Target platform is c64basic / MOS6502X // Global Constants & labels .const OFFSET_STRUCT_FOO_THING2 = 1 .const OFFSET_STRUCT_FOO_THING3 = 2 - .label bar_thing3 = 4 // @begin __bbegin: - // [0] (byte) bar_thing1 ← (byte) 'a' -- vbum1=vbuc1 + // [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2 lda #'a' - sta bar_thing1 - // [1] (byte) bar_thing2 ← (byte) 'b' -- vbum1=vbuc1 + sta bar + // [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2 lda #'b' - sta bar_thing2 - // [2] (const byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1 - lda #<__0 - sta.z bar_thing3 - lda #>__0 - sta.z bar_thing3+1 + sta bar+OFFSET_STRUCT_FOO_THING2 + // [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$c +!: + lda __0-1,y + sta bar+OFFSET_STRUCT_FOO_THING3-1,y + dey + bne !- // [3] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 @@ -273,7 +254,7 @@ __bend: // main main: { .label SCREEN = $400 - .label barp = bar_thing1 + .label barp = bar .label i = 3 .label j = 2 // [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2 @@ -320,43 +301,36 @@ main: { // File Data __0: .text "qwe" .byte 0 - bar_thing1: .byte 0 - bar_thing2: .byte 0 + .fill 8, 0 + bar: .byte 0, 0 REGISTER UPLIFT POTENTIAL REGISTERS -Statement [0] (byte) bar_thing1 ← (byte) 'a' [ ] ( [ ] ) always clobbers reg byte a -Statement [1] (byte) bar_thing2 ← (byte) 'b' [ ] ( [ ] ) always clobbers reg byte a -Statement [2] (const byte*) bar_thing3 ← (const string) $0 [ ] ( [ ] ) always clobbers reg byte a +Statement [0] *((byte*)&(struct foo) bar) ← (byte) 'a' [ bar ] ( [ bar ] ) always clobbers reg byte a +Statement [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' [ bar ] ( [ bar ] ) always clobbers reg byte a +Statement [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) [ ] ( [ ] ) always clobbers reg byte a reg byte y Statement [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:4 [ ] ) always clobbers reg byte a Statement [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:4 [ ] ) always clobbers reg byte a Statement [9] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) [ main::j#2 main::i#4 ] ( main:4 [ main::j#2 main::i#4 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::j#2 main::j#1 ] Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#4 main::i#3 ] -Statement [0] (byte) bar_thing1 ← (byte) 'a' [ ] ( [ ] ) always clobbers reg byte a -Statement [1] (byte) bar_thing2 ← (byte) 'b' [ ] ( [ ] ) always clobbers reg byte a -Statement [2] (const byte*) bar_thing3 ← (const string) $0 [ ] ( [ ] ) always clobbers reg byte a +Statement [0] *((byte*)&(struct foo) bar) ← (byte) 'a' [ bar ] ( [ bar ] ) always clobbers reg byte a +Statement [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' [ bar ] ( [ bar ] ) always clobbers reg byte a +Statement [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) [ ] ( [ ] ) always clobbers reg byte a reg byte y Statement [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:4 [ ] ) always clobbers reg byte a Statement [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:4 [ ] ) always clobbers reg byte a Statement [9] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) [ main::j#2 main::i#4 ] ( main:4 [ main::j#2 main::i#4 ] ) always clobbers reg byte a Potential registers zp[1]:2 [ main::j#2 main::j#1 ] : zp[1]:2 , reg byte x , reg byte y , Potential registers zp[1]:3 [ main::i#4 main::i#3 ] : zp[1]:3 , reg byte x , reg byte y , -Potential registers mem[1] [ bar_thing1 ] : mem[1] , -Potential registers mem[1] [ bar_thing2 ] : mem[1] , -Potential registers zp[2]:4 [ bar_thing3 ] : zp[2]:4 , +Potential registers mem[14] [ bar ] : mem[14] , REGISTER UPLIFT SCOPES -Uplift Scope [] 20: mem[1] [ bar_thing1 ] 20: mem[1] [ bar_thing2 ] 20: zp[2]:4 [ bar_thing3 ] Uplift Scope [main] 27.5: zp[1]:2 [ main::j#2 main::j#1 ] 23.83: zp[1]:3 [ main::i#4 main::i#3 ] Uplift Scope [foo] +Uplift Scope [] 0: mem[14] [ bar ] -Uplifting [] best 576 combination mem[1] [ bar_thing1 ] mem[1] [ bar_thing2 ] zp[2]:4 [ bar_thing3 ] -Uplifting [main] best 366 combination reg byte y [ main::j#2 main::j#1 ] reg byte x [ main::i#4 main::i#3 ] -Uplifting [foo] best 366 combination -Attempting to uplift remaining variables inmem[1] [ bar_thing1 ] -Uplifting [] best 366 combination mem[1] [ bar_thing1 ] -Attempting to uplift remaining variables inmem[1] [ bar_thing2 ] -Uplifting [] best 366 combination mem[1] [ bar_thing2 ] -Allocated (was zp[2]:4) zp[2]:2 [ bar_thing3 ] +Uplifting [main] best 372 combination reg byte y [ main::j#2 main::j#1 ] reg byte x [ main::i#4 main::i#3 ] +Uplifting [foo] best 372 combination +Uplifting [] best 372 combination mem[14] [ bar ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -369,20 +343,21 @@ ASSEMBLER BEFORE OPTIMIZATION // Global Constants & labels .const OFFSET_STRUCT_FOO_THING2 = 1 .const OFFSET_STRUCT_FOO_THING3 = 2 - .label bar_thing3 = 2 // @begin __bbegin: - // [0] (byte) bar_thing1 ← (byte) 'a' -- vbum1=vbuc1 + // [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2 lda #'a' - sta bar_thing1 - // [1] (byte) bar_thing2 ← (byte) 'b' -- vbum1=vbuc1 + sta bar + // [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2 lda #'b' - sta bar_thing2 - // [2] (const byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1 - lda #<__0 - sta.z bar_thing3 - lda #>__0 - sta.z bar_thing3+1 + sta bar+OFFSET_STRUCT_FOO_THING2 + // [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$c +!: + lda __0-1,y + sta bar+OFFSET_STRUCT_FOO_THING3-1,y + dey + bne !- // [3] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 @@ -398,7 +373,7 @@ __bend: // main main: { .label SCREEN = $400 - .label barp = bar_thing1 + .label barp = bar // [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2 lda barp sta SCREEN @@ -438,8 +413,8 @@ main: { // File Data __0: .text "qwe" .byte 0 - bar_thing1: .byte 0 - bar_thing2: .byte 0 + .fill 8, 0 + bar: .byte 0, 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 @@ -463,23 +438,21 @@ Removing instruction jmp __b1 Succesful ASM optimization Pass5NextJumpElimination FINAL SYMBOL TABLE -(const string) $0 = (string) "qwe" +(const byte*) $0[(number) $c] = (string) "qwe" (label) @1 (label) @begin (label) @end (const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1 (const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2 -(byte) bar_thing1 loadstore mem[1] 20.0 -(byte) bar_thing2 loadstore mem[1] 20.0 -(const byte*) bar_thing3 loadstore zp[2]:2 20.0 +(struct foo) bar loadstore mem[14] (byte) foo::thing1 (byte) foo::thing2 -(const byte*) foo::thing3 = { fill( $c, 0) } +(const byte*) foo::thing3[(number) $c] = { fill( $c, 0) } (void()) main() (label) main::@1 (label) main::@return (const byte*) main::SCREEN = (byte*) 1024 -(const struct foo*) main::barp = (struct foo*)&(byte) bar_thing1 +(const struct foo*) main::barp = &(struct foo) bar (byte) main::i (byte) main::i#3 reg byte x 7.333333333333333 (byte) main::i#4 reg byte x 16.5 @@ -489,13 +462,11 @@ FINAL SYMBOL TABLE reg byte y [ main::j#2 main::j#1 ] reg byte x [ main::i#4 main::i#3 ] -mem[1] [ bar_thing1 ] -mem[1] [ bar_thing2 ] -zp[2]:2 [ bar_thing3 ] +mem[14] [ bar ] FINAL ASSEMBLER -Score: 276 +Score: 282 // File Comments // Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) @@ -507,21 +478,22 @@ Score: 276 // Global Constants & labels .const OFFSET_STRUCT_FOO_THING2 = 1 .const OFFSET_STRUCT_FOO_THING3 = 2 - .label bar_thing3 = 2 // @begin __bbegin: // bar = { 'a', 'b', "qwe" } - // [0] (byte) bar_thing1 ← (byte) 'a' -- vbum1=vbuc1 + // [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2 lda #'a' - sta bar_thing1 - // [1] (byte) bar_thing2 ← (byte) 'b' -- vbum1=vbuc1 + sta bar + // [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2 lda #'b' - sta bar_thing2 - // [2] (const byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1 - lda #<__0 - sta.z bar_thing3 - lda #>__0 - sta.z bar_thing3+1 + sta bar+OFFSET_STRUCT_FOO_THING2 + // [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$c +!: + lda __0-1,y + sta bar+OFFSET_STRUCT_FOO_THING3-1,y + dey + bne !- // [3] phi from @begin to @1 [phi:@begin->@1] // @1 // [4] call main @@ -532,7 +504,7 @@ __bbegin: // main main: { .label SCREEN = $400 - .label barp = bar_thing1 + .label barp = bar // SCREEN[i++] = barp->thing1 // [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2 lda barp @@ -572,6 +544,6 @@ main: { // File Data __0: .text "qwe" .byte 0 - bar_thing1: .byte 0 - bar_thing2: .byte 0 + .fill 8, 0 + bar: .byte 0, 0 diff --git a/src/test/ref/declared-memory-var-4.sym b/src/test/ref/declared-memory-var-4.sym index 8fcbe836f..a3ff096a3 100644 --- a/src/test/ref/declared-memory-var-4.sym +++ b/src/test/ref/declared-memory-var-4.sym @@ -1,3 +1,4 @@ +(const byte*) $0[(number) $c] = (string) "qwe" (label) @1 (label) @begin (label) @end diff --git a/src/test/ref/sizeof-struct.log b/src/test/ref/sizeof-struct.log index 4be59c0e9..0bf9ffbda 100644 --- a/src/test/ref/sizeof-struct.log +++ b/src/test/ref/sizeof-struct.log @@ -9,12 +9,12 @@ Converted struct value to member variables (struct Circle) main::c Created struct value member variable (byte) main::c_center_x Created struct value member variable (byte) main::c_center_y Converted struct value to member variables (struct Point) main::c_center -Adding struct value member variable default initializer (byte) main::p_x ← (byte) 0 -Adding struct value member variable default initializer (byte) main::p_y ← (byte) 0 -Adding struct value member variable default initializer (struct Point) main::c_center ← {} -Adding struct value member variable default initializer (byte) main::c_radius ← (byte) 0 -Adding struct value member variable default initializer (byte) main::c_center_x ← (byte) 0 -Adding struct value member variable default initializer (byte) main::c_center_y ← (byte) 0 +Adding struct value member variable copy (byte) main::p_x ← (byte) 0 +Adding struct value member variable copy (byte) main::p_y ← (byte) 0 +Adding struct value member variable copy (struct Point) main::c_center ← { x: (byte) 0, y: (byte) 0 } +Adding struct value member variable copy (byte) main::c_radius ← (byte) 0 +Adding struct value member variable copy (byte) main::c_center_x ← (byte) 0 +Adding struct value member variable copy (byte) main::c_center_y ← (byte) 0 Identified constant variable (byte) main::p_x Identified constant variable (byte) main::p_y Identified constant variable (byte) main::c_radius diff --git a/src/test/ref/struct-0.log b/src/test/ref/struct-0.log index 1d6b0ebc5..766d30794 100644 --- a/src/test/ref/struct-0.log +++ b/src/test/ref/struct-0.log @@ -1,8 +1,8 @@ Created struct value member variable (byte) point_x Created struct value member variable (byte) point_y Converted struct value to member variables (struct Point) point -Adding struct value member variable default initializer (byte) point_x ← (byte) 0 -Adding struct value member variable default initializer (byte) point_y ← (byte) 0 +Adding struct value member variable copy (byte) point_x ← (byte) 0 +Adding struct value member variable copy (byte) point_y ← (byte) 0 Replacing struct member reference (struct Point) point.x with member unwinding reference (byte) point_x Replacing struct member reference (struct Point) point.y with member unwinding reference (byte) point_y Replacing struct member reference (struct Point) point.x with member unwinding reference (byte) point_x diff --git a/src/test/ref/struct-1.log b/src/test/ref/struct-1.log index b0dc5e131..367c06936 100644 --- a/src/test/ref/struct-1.log +++ b/src/test/ref/struct-1.log @@ -4,10 +4,10 @@ Converted struct value to member variables (struct Point) point1 Created struct value member variable (byte) point2_x Created struct value member variable (byte) point2_y Converted struct value to member variables (struct Point) point2 -Adding struct value member variable default initializer (byte) point1_x ← (byte) 0 -Adding struct value member variable default initializer (byte) point1_y ← (byte) 0 -Adding struct value member variable default initializer (byte) point2_x ← (byte) 0 -Adding struct value member variable default initializer (byte) point2_y ← (byte) 0 +Adding struct value member variable copy (byte) point1_x ← (byte) 0 +Adding struct value member variable copy (byte) point1_y ← (byte) 0 +Adding struct value member variable copy (byte) point2_x ← (byte) 0 +Adding struct value member variable copy (byte) point2_y ← (byte) 0 Replacing struct member reference (struct Point) point1.x with member unwinding reference (byte) point1_x Replacing struct member reference (struct Point) point1.y with member unwinding reference (byte) point1_y Replacing struct member reference (struct Point) point1.y with member unwinding reference (byte) point1_y diff --git a/src/test/ref/struct-11.asm b/src/test/ref/struct-11.asm index eb324e2bd..bcda9f4f4 100644 --- a/src/test/ref/struct-11.asm +++ b/src/test/ref/struct-11.asm @@ -1,273 +1,78 @@ // Example of a struct containing an array +// Works because the struct is only handled as a value .pc = $801 "Basic" -:BasicUpstart(main) +:BasicUpstart(__bbegin) .pc = $80d "Program" - .const jesper_id = $1b244 - .const henry_id = $4466d - .label print_char_cursor = $a - .label print_line_cursor = 8 + .label SCREEN = $400 + .const jesper_id = 4 + .const henriette_id = 7 +__bbegin: + ldy #$40 +!: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- + ldy #$40 +!: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- + jsr main + rts main: { - lda #<$400 - sta.z print_line_cursor - lda #>$400 - sta.z print_line_cursor+1 - lda #jesper_initials - sta.z print_person.person_initials+1 - lda #<$400 - sta.z print_char_cursor - lda #>$400 - sta.z print_char_cursor+1 - lda #jesper_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>jesper_id>>$10 - sta.z print_person.person_id+3 - jsr print_person - lda.z print_line_cursor - sta.z print_char_cursor - lda.z print_line_cursor+1 - sta.z print_char_cursor+1 - lda #henry_initials - sta.z print_person.person_initials+1 - lda #henry_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>henry_id>>$10 - sta.z print_person.person_id+3 - jsr print_person - rts -} -// print_person(dword zeropage(2) person_id, byte* zeropage(6) person_initials) -print_person: { - .label person_id = 2 - .label person_initials = 6 - jsr print_dword_decimal - jsr print_char - lda.z person_initials - sta.z print_str.str - lda.z person_initials+1 - sta.z print_str.str+1 - jsr print_str - jsr print_ln - rts -} -// Print a newline -print_ln: { - __b1: - lda #$28 - clc - adc.z print_line_cursor - sta.z print_line_cursor - bcc !+ - inc.z print_line_cursor+1 - !: - lda.z print_line_cursor+1 - cmp.z print_char_cursor+1 - bcc __b1 - bne !+ - lda.z print_line_cursor - cmp.z print_char_cursor - bcc __b1 - !: - rts -} -// Print a zero-terminated string -// print_str(byte* zeropage($d) str) -print_str: { - .label str = $d - __b1: + lda #jesper_name + sta.z print_person.person_name+1 ldy #0 - lda (str),y + ldx #jesper_id + jsr print_person + lda #henriette_name + sta.z print_person.person_name+1 + ldx #henriette_id + jsr print_person + rts +} +// print_person(byte register(X) person_id, byte* zp(2) person_name) +print_person: { + .label person_name = 2 + lda DIGIT,x + sta SCREEN,y + tya + tax + inx + lda #' ' + sta SCREEN,x + inx + ldy #0 + __b1: + lda (person_name),y cmp #0 bne __b2 - rts - __b2: - ldy #0 - lda (str),y - sta (print_char_cursor),y - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - inc.z str - bne !+ - inc.z str+1 - !: - jmp __b1 -} -// Print a single char -print_char: { - .const ch = ' ' - lda #ch - ldy #0 - sta (print_char_cursor),y - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - rts -} -// Print a dword as DECIMAL -// print_dword_decimal(dword zeropage(2) w) -print_dword_decimal: { - .label w = 2 - jsr ultoa - lda #decimal_digits_long - sta.z print_str.str+1 - jsr print_str - rts -} -// Converts unsigned number value to a string representing it in RADIX format. -// If the leading digits are zero they are not included in the string. -// - value : The number to be converted to RADIX -// - buffer : receives the string representing the number and zero-termination. -// - radix : The radix to convert the number to (from the enum RADIX) -// ultoa(dword zeropage(2) value, byte* zeropage($d) buffer) -ultoa: { - .const max_digits = $a - .label digit_value = $f - .label buffer = $d - .label digit = $c - .label value = 2 - lda #decimal_digits_long - sta.z buffer+1 - ldx #0 + lda #' ' + sta SCREEN,x txa - sta.z digit - __b1: - lda.z digit - cmp #max_digits-1 - bcc __b2 - lda.z value tay - lda DIGITS,y - ldy #0 - sta (buffer),y - inc.z buffer - bne !+ - inc.z buffer+1 - !: - lda #0 - tay - sta (buffer),y - rts - __b2: - lda.z digit - asl - asl - tay - lda RADIX_DECIMAL_VALUES_LONG,y - sta.z digit_value - lda RADIX_DECIMAL_VALUES_LONG+1,y - sta.z digit_value+1 - lda RADIX_DECIMAL_VALUES_LONG+2,y - sta.z digit_value+2 - lda RADIX_DECIMAL_VALUES_LONG+3,y - sta.z digit_value+3 - cpx #0 - bne __b5 - lda.z value+3 - cmp.z digit_value+3 - bcc !+ - bne __b5 - lda.z value+2 - cmp.z digit_value+2 - bcc !+ - bne __b5 - lda.z value+1 - cmp.z digit_value+1 - bcc !+ - bne __b5 - lda.z value - cmp.z digit_value - bcs __b5 - !: - __b4: - inc.z digit - jmp __b1 - __b5: - jsr ultoa_append - inc.z buffer - bne !+ - inc.z buffer+1 - !: - ldx #1 - jmp __b4 -} -// Used to convert a single digit of an unsigned number value to a string representation -// Counts a single digit up from '0' as long as the value is larger than sub. -// Each time the digit is increased sub is subtracted from value. -// - buffer : pointer to the char that receives the digit -// - value : The value where the digit will be derived from -// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. -// (For decimal the subs used are 10000, 1000, 100, 10, 1) -// returns : the value reduced by sub * digit so that it is less than sub. -// ultoa_append(byte* zeropage($d) buffer, dword zeropage(2) value, dword zeropage($f) sub) -ultoa_append: { - .label buffer = $d - .label value = 2 - .label sub = $f - .label return = 2 - ldx #0 - __b1: - lda.z value+3 - cmp.z sub+3 - bcc !+ - bne __b2 - lda.z value+2 - cmp.z sub+2 - bcc !+ - bne __b2 - lda.z value+1 - cmp.z sub+1 - bcc !+ - bne __b2 - lda.z value - cmp.z sub - bcs __b2 - !: - lda DIGITS,x - ldy #0 - sta (buffer),y + iny rts __b2: + lda (person_name),y + sta SCREEN,x inx - lda.z value - sec - sbc.z sub - sta.z value - lda.z value+1 - sbc.z sub+1 - sta.z value+1 - lda.z value+2 - sbc.z sub+2 - sta.z value+2 - lda.z value+3 - sbc.z sub+3 - sta.z value+3 + iny jmp __b1 } - // The digits used for numbers - DIGITS: .text "0123456789abcdef" - // Values of decimal digits - RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a - // Digits used for storing the decimal word - decimal_digits_long: .fill $b, 0 - jesper_initials: .text "jg" + DIGIT: .text "0123456789" .byte 0 - henry_initials: .text "hg" + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 + __0: .text "jesper" .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 diff --git a/src/test/ref/struct-11.cfg b/src/test/ref/struct-11.cfg index eeb8abab0..eb962e794 100644 --- a/src/test/ref/struct-11.cfg +++ b/src/test/ref/struct-11.cfg @@ -1,167 +1,51 @@ @begin: scope:[] from - [0] phi() + [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) + [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) to:@1 @1: scope:[] from @begin - [1] phi() - [2] call main + [2] phi() + [3] call main to:@end @end: scope:[] from @1 - [3] phi() + [4] phi() (void()) main() main: scope:[main] from @1 - [4] phi() - [5] call print_person + [5] phi() + [6] call print_person to:main::@1 main::@1: scope:[main] from main - [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 - [7] call print_person + [7] phi() + [8] call print_person to:main::@return main::@return: scope:[main] from main::@1 - [8] return + [9] return to:@return -(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 - [9] (byte*) print_line_cursor#20 ← phi( main/(byte*) 1024 main::@1/(byte*) print_line_cursor#1 ) - [9] (byte*) print_person::person_initials#2 ← phi( main/(const byte*) jesper_initials main::@1/(const byte*) henry_initials ) - [9] (byte*) print_char_cursor#39 ← phi( main/(byte*) 1024 main::@1/(byte*) print_char_cursor#47 ) - [9] (dword) print_person::person_id#2 ← phi( main/(const dword) jesper_id main::@1/(const dword) henry_id ) - [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 - [11] call print_dword_decimal + [10] (byte*) print_person::person_name#4 ← phi( main/(const byte*) jesper_name main::@1/(const byte*) henriette_name ) + [10] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) + [10] (byte) print_person::person_id#2 ← phi( main/(const byte) jesper_id main::@1/(const byte) henriette_id ) + [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) + [12] (byte) idx#4 ← ++ (byte) idx#13 + [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' + [14] (byte) idx#5 ← ++ (byte) idx#4 to:print_person::@1 -print_person::@1: scope:[print_person] from print_person - [12] phi() - [13] call print_char - to:print_person::@2 -print_person::@2: scope:[print_person] from print_person::@1 - [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 - [15] call print_str +print_person::@1: scope:[print_person] from print_person print_person::@2 + [15] (byte) idx#14 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 ) + [15] (byte) print_person::i#2 ← phi( print_person/(byte) 0 print_person::@2/(byte) print_person::i#1 ) + [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 to:print_person::@3 -print_person::@3: scope:[print_person] from print_person::@2 - [16] phi() - [17] call print_ln +print_person::@3: scope:[print_person] from print_person::@1 + [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' + [18] (byte) idx#16 ← ++ (byte) idx#14 to:print_person::@return print_person::@return: scope:[print_person] from print_person::@3 - [18] return + [19] return to:@return - -(void()) print_ln() -print_ln: scope:[print_ln] from print_person::@3 - [19] phi() - to:print_ln::@1 -print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 - [20] (byte*) print_line_cursor#9 ← phi( print_ln/(byte*) print_line_cursor#20 print_ln::@1/(byte*) print_line_cursor#1 ) - [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 - [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 - to:print_ln::@return -print_ln::@return: scope:[print_ln] from print_ln::@1 - [23] return - to:@return - -(void()) print_str((byte*) print_str::str) -print_str: scope:[print_str] from print_dword_decimal::@1 print_person::@2 - [24] (byte*) print_char_cursor#41 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#39 print_person::@2/(byte*) print_char_cursor#25 ) - [24] (byte*) print_str::str#5 ← phi( print_dword_decimal::@1/(const byte*) decimal_digits_long print_person::@2/(byte*) print_str::str#2 ) - to:print_str::@1 -print_str::@1: scope:[print_str] from print_str print_str::@2 - [25] (byte*) print_char_cursor#18 ← phi( print_str/(byte*) print_char_cursor#41 print_str::@2/(byte*) print_char_cursor#1 ) - [25] (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 ) - [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 - to:print_str::@return -print_str::@return: scope:[print_str] from print_str::@1 - [27] return - to:@return -print_str::@2: scope:[print_str] from print_str::@1 - [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) - [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 - [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 - to:print_str::@1 - -(void()) print_char((byte) print_char::ch) -print_char: scope:[print_char] from print_person::@1 - [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 - [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 - to:print_char::@return -print_char::@return: scope:[print_char] from print_char - [33] return - to:@return - -(void()) print_dword_decimal((dword) print_dword_decimal::w) -print_dword_decimal: scope:[print_dword_decimal] from print_person - [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 - [35] call ultoa - to:print_dword_decimal::@1 -print_dword_decimal::@1: scope:[print_dword_decimal] from print_dword_decimal - [36] phi() - [37] call print_str - to:print_dword_decimal::@return -print_dword_decimal::@return: scope:[print_dword_decimal] from print_dword_decimal::@1 - [38] return - to:@return - -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -ultoa: scope:[ultoa] from print_dword_decimal - [39] phi() - to:ultoa::@1 -ultoa::@1: scope:[ultoa] from ultoa ultoa::@4 - [40] (byte*) ultoa::buffer#11 ← phi( ultoa::@4/(byte*) ultoa::buffer#14 ultoa/(const byte*) decimal_digits_long ) - [40] (byte) ultoa::started#2 ← phi( ultoa::@4/(byte) ultoa::started#4 ultoa/(byte) 0 ) - [40] (dword) ultoa::value#2 ← phi( ultoa::@4/(dword) ultoa::value#6 ultoa/(dword) ultoa::value#1 ) - [40] (byte) ultoa::digit#2 ← phi( ultoa::@4/(byte) ultoa::digit#1 ultoa/(byte) 0 ) - [41] if((byte) ultoa::digit#2<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 - to:ultoa::@3 -ultoa::@3: scope:[ultoa] from ultoa::@1 - [42] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#2 - [43] *((byte*) ultoa::buffer#11) ← *((const byte*) DIGITS + (byte~) ultoa::$4) - [44] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 - [45] *((byte*) ultoa::buffer#3) ← (byte) 0 - to:ultoa::@return -ultoa::@return: scope:[ultoa] from ultoa::@3 - [46] return - to:@return -ultoa::@2: scope:[ultoa] from ultoa::@1 - [47] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 << (byte) 2 - [48] (dword) ultoa::digit_value#0 ← *((const dword*) RADIX_DECIMAL_VALUES_LONG + (byte~) ultoa::$11) - [49] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 - to:ultoa::@7 -ultoa::@7: scope:[ultoa] from ultoa::@2 - [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 - to:ultoa::@4 -ultoa::@4: scope:[ultoa] from ultoa::@6 ultoa::@7 - [51] (byte*) ultoa::buffer#14 ← phi( ultoa::@7/(byte*) ultoa::buffer#11 ultoa::@6/(byte*) ultoa::buffer#4 ) - [51] (byte) ultoa::started#4 ← phi( ultoa::@7/(byte) ultoa::started#2 ultoa::@6/(byte) 1 ) - [51] (dword) ultoa::value#6 ← phi( ultoa::@7/(dword) ultoa::value#2 ultoa::@6/(dword) ultoa::value#0 ) - [52] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#2 - to:ultoa::@1 -ultoa::@5: scope:[ultoa] from ultoa::@2 ultoa::@7 - [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 - [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 - [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 - [56] call ultoa_append - [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 - to:ultoa::@6 -ultoa::@6: scope:[ultoa] from ultoa::@5 - [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 - [59] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#11 - to:ultoa::@4 - -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -ultoa_append: scope:[ultoa_append] from ultoa::@5 - [60] phi() - to:ultoa_append::@1 -ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2 - [61] (byte) ultoa_append::digit#2 ← phi( ultoa_append/(byte) 0 ultoa_append::@2/(byte) ultoa_append::digit#1 ) - [61] (dword) ultoa_append::value#2 ← phi( ultoa_append/(dword) ultoa_append::value#0 ultoa_append::@2/(dword) ultoa_append::value#1 ) - [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 - to:ultoa_append::@3 -ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1 - [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) - to:ultoa_append::@return -ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3 - [64] return - to:@return -ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1 - [65] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 - [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 - to:ultoa_append::@1 +print_person::@2: scope:[print_person] from print_person::@1 + [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) + [21] (byte) idx#6 ← ++ (byte) idx#14 + [22] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 + to:print_person::@1 diff --git a/src/test/ref/struct-11.log b/src/test/ref/struct-11.log index 29f4cd6b9..b460a6bc0 100644 --- a/src/test/ref/struct-11.log +++ b/src/test/ref/struct-11.log @@ -1,2612 +1,698 @@ -Fixing struct type size struct Person to 7 -Fixing struct type size struct Person to 7 -Fixing struct type size struct Person to 7 -Fixing pointer addition (word*~) bsearch16u::$7 ← (word*) bsearch16u::items + (byte~) bsearch16u::$6 -Fixing pointer addition (word*~) bsearch16u::$15 ← (word*) bsearch16u::pivot + (number) 1 -Fixing pointer addition (word*~) bsearch16u::$1 ← (word*) bsearch16u::items - (number) 1 -Fixing pointer array-indexing *((word*) utoa::digit_values + (byte) utoa::digit) -Fixing pointer array-indexing *((dword*) ultoa::digit_values + (byte) ultoa::digit) -Created struct value member variable (dword) jesper_id -Created struct value member variable (const byte*) jesper_initials +Fixing struct type size struct Person to 65 +Fixing struct type size struct Person to 65 +Fixing struct type size struct Person to 65 +Fixing struct type SIZE_OF struct Person to 65 +Fixing struct type SIZE_OF struct Person to 65 +Created struct value member variable (byte) jesper_id +Created struct value member variable (const byte*) jesper_name Converted struct value to member variables (struct Person) jesper -Created struct value member variable (dword) henry_id -Created struct value member variable (const byte*) henry_initials -Converted struct value to member variables (struct Person) henry -Created struct value member variable (dword) print_person::person_id -Created struct value member variable (const byte*) print_person::person_initials +Created struct value member variable (byte) henriette_id +Created struct value member variable (const byte*) henriette_name +Converted struct value to member variables (struct Person) henriette +Created struct value member variable (byte) print_person::person_id +Created struct value member variable (byte*) print_person::person_name Converted struct value to member variables (struct Person) print_person::person -Converted procedure struct value parameter to member unwinding (void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) -Adding struct value list initializer (dword) jesper_id ← (number) $1b244 -Adding struct value list initializer (const byte*) jesper_initials ← (string) "jg" -Adding struct value list initializer (dword) henry_id ← (number) $4466d -Adding struct value list initializer (const byte*) henry_initials ← (string) "hg" -Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (dword) jesper_id (const byte*) jesper_initials -Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (dword) henry_id (const byte*) henry_initials -Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (dword) print_person::person_id -Replacing struct member reference (struct Person) print_person::person.initials with member unwinding reference (const byte*) print_person::person_initials -Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src) -Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_lines::str) -Warning! Adding boolean cast to non-boolean condition (byte) print_str_lines::ch -Warning! Adding boolean cast to non-boolean condition *((byte*) print_str::str) -Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_at::str) -Warning! Adding boolean cast to non-boolean sub-expression (byte) print_str_lines::ch -Identified constant variable (byte*) HEAP_TOP -Identified constant variable (dword) jesper_id -Identified constant variable (const byte*) jesper_initials -Identified constant variable (dword) henry_id -Identified constant variable (const byte*) henry_initials -Culled Empty Block (label) @1 -Culled Empty Block (label) @2 -Culled Empty Block (label) @3 -Culled Empty Block (label) @4 -Culled Empty Block (label) @5 -Culled Empty Block (label) @6 -Culled Empty Block (label) @7 -Culled Empty Block (label) @8 -Culled Empty Block (label) @9 -Culled Empty Block (label) @10 -Culled Empty Block (label) ultoa::@13 -Culled Empty Block (label) ultoa::@5 -Culled Empty Block (label) ultoa::@14 -Culled Empty Block (label) ultoa::@6 -Culled Empty Block (label) ultoa::@15 -Culled Empty Block (label) ultoa::@7 -Culled Empty Block (label) ultoa::@16 -Culled Empty Block (label) ultoa::@17 -Culled Empty Block (label) ultoa::@22 -Culled Empty Block (label) ultoa::@23 -Culled Empty Block (label) ultoa::@25 -Culled Empty Block (label) @11 -Culled Empty Block (label) ultoa_append::@4 -Culled Empty Block (label) ultoa_append::@5 -Culled Empty Block (label) ultoa_append::@6 -Culled Empty Block (label) ultoa_append::@7 -Culled Empty Block (label) @13 -Culled Empty Block (label) @14 -Culled Empty Block (label) print_str::@4 -Culled Empty Block (label) print_str::@3 -Culled Empty Block (label) print_str::@5 -Culled Empty Block (label) print_str::@6 -Culled Empty Block (label) @15 -Culled Empty Block (label) @16 -Culled Empty Block (label) @17 -Culled Empty Block (label) @18 -Culled Empty Block (label) @19 -Culled Empty Block (label) @20 -Culled Empty Block (label) @21 -Culled Empty Block (label) @22 -Culled Empty Block (label) @23 -Culled Empty Block (label) @24 -Culled Empty Block (label) @25 -Culled Empty Block (label) @26 -Culled Empty Block (label) @27 -Culled Empty Block (label) @28 -Culled Empty Block (label) @29 -Culled Empty Block (label) @30 -Culled Empty Block (label) @31 -Culled Empty Block (label) @32 -Culled Empty Block (label) @33 -Culled Empty Block (label) @34 -Culled Empty Block (label) @35 -Culled Empty Block (label) @36 -Culled Empty Block (label) @37 +Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) +Adding struct value member variable copy (byte) jesper_id ← (byte) 4 +Adding struct value member variable copy *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) +Adding struct value member variable copy (byte) henriette_id ← (byte) 7 +Adding struct value member variable copy *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) +Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) jesper_id (const byte*) jesper_name +Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) henriette_id (const byte*) henriette_name +Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id +Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name +Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name +Warning! Adding boolean cast to non-boolean condition *((byte*) print_person::person_name + (byte) print_person::i) +Identified constant variable (byte) jesper_id +Identified constant variable (byte) henriette_id +Culled Empty Block (label) print_person::@4 +Culled Empty Block (label) print_person::@5 +Culled Empty Block (label) print_person::@6 CONTROL FLOW GRAPH SSA @begin: scope:[] from - to:@12 - -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -ultoa: scope:[ultoa] from print_dword_decimal - (byte*) ultoa::buffer#21 ← phi( print_dword_decimal/(byte*) ultoa::buffer#5 ) - (dword) ultoa::value#12 ← phi( print_dword_decimal/(dword) ultoa::value#1 ) - (byte) ultoa::radix#1 ← phi( print_dword_decimal/(byte) ultoa::radix#0 ) - (byte) ultoa::max_digits#0 ← (byte) 0 - (dword*) ultoa::digit_values#0 ← (dword*) 0 - (bool~) ultoa::$0 ← (byte) ultoa::radix#1 == (const byte) DECIMAL - if((bool~) ultoa::$0) goto ultoa::@1 - to:ultoa::@9 -ultoa::@1: scope:[ultoa] from ultoa - (byte*) ultoa::buffer#17 ← phi( ultoa/(byte*) ultoa::buffer#21 ) - (dword) ultoa::value#8 ← phi( ultoa/(dword) ultoa::value#12 ) - (byte) ultoa::max_digits#1 ← (number) $a - (dword*) ultoa::digit_values#1 ← (const dword*) RADIX_DECIMAL_VALUES_LONG - to:ultoa::@8 -ultoa::@9: scope:[ultoa] from ultoa - (dword) ultoa::value#13 ← phi( ultoa/(dword) ultoa::value#12 ) - (byte*) ultoa::buffer#16 ← phi( ultoa/(byte*) ultoa::buffer#21 ) - (byte) ultoa::radix#2 ← phi( ultoa/(byte) ultoa::radix#1 ) - (bool~) ultoa::$1 ← (byte) ultoa::radix#2 == (const byte) HEXADECIMAL - if((bool~) ultoa::$1) goto ultoa::@2 - to:ultoa::@10 -ultoa::@2: scope:[ultoa] from ultoa::@9 - (byte*) ultoa::buffer#18 ← phi( ultoa::@9/(byte*) ultoa::buffer#16 ) - (dword) ultoa::value#9 ← phi( ultoa::@9/(dword) ultoa::value#13 ) - (byte) ultoa::max_digits#2 ← (number) 8 - (dword*) ultoa::digit_values#2 ← (const dword*) RADIX_HEXADECIMAL_VALUES_LONG - to:ultoa::@8 -ultoa::@10: scope:[ultoa] from ultoa::@9 - (dword) ultoa::value#14 ← phi( ultoa::@9/(dword) ultoa::value#13 ) - (byte*) ultoa::buffer#13 ← phi( ultoa::@9/(byte*) ultoa::buffer#16 ) - (byte) ultoa::radix#3 ← phi( ultoa::@9/(byte) ultoa::radix#2 ) - (bool~) ultoa::$2 ← (byte) ultoa::radix#3 == (const byte) OCTAL - if((bool~) ultoa::$2) goto ultoa::@3 - to:ultoa::@11 -ultoa::@3: scope:[ultoa] from ultoa::@10 - (byte*) ultoa::buffer#19 ← phi( ultoa::@10/(byte*) ultoa::buffer#13 ) - (dword) ultoa::value#10 ← phi( ultoa::@10/(dword) ultoa::value#14 ) - (byte) ultoa::max_digits#3 ← (number) $b - (dword*) ultoa::digit_values#3 ← (const dword*) RADIX_OCTAL_VALUES_LONG - to:ultoa::@8 -ultoa::@11: scope:[ultoa] from ultoa::@10 - (dword) ultoa::value#15 ← phi( ultoa::@10/(dword) ultoa::value#14 ) - (byte*) ultoa::buffer#10 ← phi( ultoa::@10/(byte*) ultoa::buffer#13 ) - (byte) ultoa::radix#4 ← phi( ultoa::@10/(byte) ultoa::radix#3 ) - (bool~) ultoa::$3 ← (byte) ultoa::radix#4 == (const byte) BINARY - if((bool~) ultoa::$3) goto ultoa::@4 - to:ultoa::@12 -ultoa::@4: scope:[ultoa] from ultoa::@11 - (byte*) ultoa::buffer#20 ← phi( ultoa::@11/(byte*) ultoa::buffer#10 ) - (dword) ultoa::value#11 ← phi( ultoa::@11/(dword) ultoa::value#15 ) - (byte) ultoa::max_digits#4 ← (number) $20 - (dword*) ultoa::digit_values#4 ← (const dword*) RADIX_BINARY_VALUES_LONG - to:ultoa::@8 -ultoa::@12: scope:[ultoa] from ultoa::@11 - (byte*) ultoa::buffer#6 ← phi( ultoa::@11/(byte*) ultoa::buffer#10 ) - *((byte*) ultoa::buffer#6) ← (byte) 'e' - (byte*) ultoa::buffer#0 ← ++ (byte*) ultoa::buffer#6 - *((byte*) ultoa::buffer#0) ← (byte) 'r' - (byte*) ultoa::buffer#1 ← ++ (byte*) ultoa::buffer#0 - *((byte*) ultoa::buffer#1) ← (byte) 'r' - (byte*) ultoa::buffer#2 ← ++ (byte*) ultoa::buffer#1 - *((byte*) ultoa::buffer#2) ← (number) 0 - to:ultoa::@return -ultoa::@return: scope:[ultoa] from ultoa::@12 ultoa::@20 - return - to:@return -ultoa::@8: scope:[ultoa] from ultoa::@1 ultoa::@2 ultoa::@3 ultoa::@4 - (byte*) ultoa::buffer#15 ← phi( ultoa::@1/(byte*) ultoa::buffer#17 ultoa::@2/(byte*) ultoa::buffer#18 ultoa::@3/(byte*) ultoa::buffer#19 ultoa::@4/(byte*) ultoa::buffer#20 ) - (dword) ultoa::value#7 ← phi( ultoa::@1/(dword) ultoa::value#8 ultoa::@2/(dword) ultoa::value#9 ultoa::@3/(dword) ultoa::value#10 ultoa::@4/(dword) ultoa::value#11 ) - (dword*) ultoa::digit_values#8 ← phi( ultoa::@1/(dword*) ultoa::digit_values#1 ultoa::@2/(dword*) ultoa::digit_values#2 ultoa::@3/(dword*) ultoa::digit_values#3 ultoa::@4/(dword*) ultoa::digit_values#4 ) - (byte) ultoa::max_digits#7 ← phi( ultoa::@1/(byte) ultoa::max_digits#1 ultoa::@2/(byte) ultoa::max_digits#2 ultoa::@3/(byte) ultoa::max_digits#3 ultoa::@4/(byte) ultoa::max_digits#4 ) - (byte) ultoa::started#0 ← (number) 0 - (byte) ultoa::digit#0 ← (number) 0 - to:ultoa::@18 -ultoa::@18: scope:[ultoa] from ultoa::@21 ultoa::@8 - (byte*) ultoa::buffer#11 ← phi( ultoa::@21/(byte*) ultoa::buffer#14 ultoa::@8/(byte*) ultoa::buffer#15 ) - (byte) ultoa::started#3 ← phi( ultoa::@21/(byte) ultoa::started#4 ultoa::@8/(byte) ultoa::started#0 ) - (dword) ultoa::value#5 ← phi( ultoa::@21/(dword) ultoa::value#6 ultoa::@8/(dword) ultoa::value#7 ) - (dword*) ultoa::digit_values#6 ← phi( ultoa::@21/(dword*) ultoa::digit_values#7 ultoa::@8/(dword*) ultoa::digit_values#8 ) - (byte) ultoa::digit#2 ← phi( ultoa::@21/(byte) ultoa::digit#1 ultoa::@8/(byte) ultoa::digit#0 ) - (byte) ultoa::max_digits#5 ← phi( ultoa::@21/(byte) ultoa::max_digits#6 ultoa::@8/(byte) ultoa::max_digits#7 ) - (number~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (number) 1 - (bool~) ultoa::$6 ← (byte) ultoa::digit#2 < (number~) ultoa::$5 - if((bool~) ultoa::$6) goto ultoa::@19 - to:ultoa::@20 -ultoa::@19: scope:[ultoa] from ultoa::@18 - (byte) ultoa::max_digits#8 ← phi( ultoa::@18/(byte) ultoa::max_digits#5 ) - (byte*) ultoa::buffer#12 ← phi( ultoa::@18/(byte*) ultoa::buffer#11 ) - (byte) ultoa::started#2 ← phi( ultoa::@18/(byte) ultoa::started#3 ) - (dword) ultoa::value#2 ← phi( ultoa::@18/(dword) ultoa::value#5 ) - (dword*) ultoa::digit_values#5 ← phi( ultoa::@18/(dword*) ultoa::digit_values#6 ) - (byte) ultoa::digit#3 ← phi( ultoa::@18/(byte) ultoa::digit#2 ) - (byte~) ultoa::$11 ← (byte) ultoa::digit#3 * (const byte) SIZEOF_DWORD - (dword) ultoa::digit_value#0 ← *((dword*) ultoa::digit_values#5 + (byte~) ultoa::$11) - (bool~) ultoa::$7 ← (dword) ultoa::value#2 >= (dword) ultoa::digit_value#0 - (bool~) ultoa::$8 ← (byte) ultoa::started#2 || (bool~) ultoa::$7 - (bool~) ultoa::$9 ← ! (bool~) ultoa::$8 - if((bool~) ultoa::$9) goto ultoa::@21 - to:ultoa::@24 -ultoa::@20: scope:[ultoa] from ultoa::@18 - (byte*) ultoa::buffer#7 ← phi( ultoa::@18/(byte*) ultoa::buffer#11 ) - (dword) ultoa::value#3 ← phi( ultoa::@18/(dword) ultoa::value#5 ) - (byte~) ultoa::$4 ← ((byte)) (dword) ultoa::value#3 - *((byte*) ultoa::buffer#7) ← *((const byte*) DIGITS + (byte~) ultoa::$4) - (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#7 - *((byte*) ultoa::buffer#3) ← (number) 0 - to:ultoa::@return -ultoa::@21: scope:[ultoa] from ultoa::@19 ultoa::@26 - (byte*) ultoa::buffer#14 ← phi( ultoa::@19/(byte*) ultoa::buffer#12 ultoa::@26/(byte*) ultoa::buffer#4 ) - (byte) ultoa::started#4 ← phi( ultoa::@19/(byte) ultoa::started#2 ultoa::@26/(byte) ultoa::started#1 ) - (dword) ultoa::value#6 ← phi( ultoa::@19/(dword) ultoa::value#2 ultoa::@26/(dword) ultoa::value#0 ) - (dword*) ultoa::digit_values#7 ← phi( ultoa::@19/(dword*) ultoa::digit_values#5 ultoa::@26/(dword*) ultoa::digit_values#9 ) - (byte) ultoa::max_digits#6 ← phi( ultoa::@19/(byte) ultoa::max_digits#8 ultoa::@26/(byte) ultoa::max_digits#9 ) - (byte) ultoa::digit#4 ← phi( ultoa::@19/(byte) ultoa::digit#3 ultoa::@26/(byte) ultoa::digit#5 ) - (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#4 - to:ultoa::@18 -ultoa::@24: scope:[ultoa] from ultoa::@19 - (dword*) ultoa::digit_values#10 ← phi( ultoa::@19/(dword*) ultoa::digit_values#5 ) - (byte) ultoa::max_digits#10 ← phi( ultoa::@19/(byte) ultoa::max_digits#8 ) - (byte) ultoa::digit#6 ← phi( ultoa::@19/(byte) ultoa::digit#3 ) - (dword) ultoa::digit_value#1 ← phi( ultoa::@19/(dword) ultoa::digit_value#0 ) - (dword) ultoa::value#4 ← phi( ultoa::@19/(dword) ultoa::value#2 ) - (byte*) ultoa::buffer#8 ← phi( ultoa::@19/(byte*) ultoa::buffer#12 ) - (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#8 - (dword) ultoa_append::value#0 ← (dword) ultoa::value#4 - (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#1 - call ultoa_append - (dword) ultoa_append::return#0 ← (dword) ultoa_append::return#2 - to:ultoa::@26 -ultoa::@26: scope:[ultoa] from ultoa::@24 - (dword*) ultoa::digit_values#9 ← phi( ultoa::@24/(dword*) ultoa::digit_values#10 ) - (byte) ultoa::max_digits#9 ← phi( ultoa::@24/(byte) ultoa::max_digits#10 ) - (byte) ultoa::digit#5 ← phi( ultoa::@24/(byte) ultoa::digit#6 ) - (byte*) ultoa::buffer#9 ← phi( ultoa::@24/(byte*) ultoa::buffer#8 ) - (dword) ultoa_append::return#3 ← phi( ultoa::@24/(dword) ultoa_append::return#0 ) - (dword~) ultoa::$10 ← (dword) ultoa_append::return#3 - (dword) ultoa::value#0 ← (dword~) ultoa::$10 - (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#9 - (byte) ultoa::started#1 ← (number) 1 - to:ultoa::@21 - -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -ultoa_append: scope:[ultoa_append] from ultoa::@24 - (byte*) ultoa_append::buffer#3 ← phi( ultoa::@24/(byte*) ultoa_append::buffer#0 ) - (dword) ultoa_append::sub#3 ← phi( ultoa::@24/(dword) ultoa_append::sub#0 ) - (dword) ultoa_append::value#5 ← phi( ultoa::@24/(dword) ultoa_append::value#0 ) - (byte) ultoa_append::digit#0 ← (number) 0 - to:ultoa_append::@1 -ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2 - (byte*) ultoa_append::buffer#2 ← phi( ultoa_append/(byte*) ultoa_append::buffer#3 ultoa_append::@2/(byte*) ultoa_append::buffer#4 ) - (byte) ultoa_append::digit#4 ← phi( ultoa_append/(byte) ultoa_append::digit#0 ultoa_append::@2/(byte) ultoa_append::digit#1 ) - (dword) ultoa_append::sub#1 ← phi( ultoa_append/(dword) ultoa_append::sub#3 ultoa_append::@2/(dword) ultoa_append::sub#2 ) - (dword) ultoa_append::value#2 ← phi( ultoa_append/(dword) ultoa_append::value#5 ultoa_append::@2/(dword) ultoa_append::value#1 ) - (bool~) ultoa_append::$0 ← (dword) ultoa_append::value#2 >= (dword) ultoa_append::sub#1 - if((bool~) ultoa_append::$0) goto ultoa_append::@2 - to:ultoa_append::@3 -ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1 - (byte*) ultoa_append::buffer#4 ← phi( ultoa_append::@1/(byte*) ultoa_append::buffer#2 ) - (dword) ultoa_append::sub#2 ← phi( ultoa_append::@1/(dword) ultoa_append::sub#1 ) - (dword) ultoa_append::value#3 ← phi( ultoa_append::@1/(dword) ultoa_append::value#2 ) - (byte) ultoa_append::digit#2 ← phi( ultoa_append::@1/(byte) ultoa_append::digit#4 ) - (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 - (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#3 - (dword) ultoa_append::sub#2 - to:ultoa_append::@1 -ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1 - (dword) ultoa_append::value#4 ← phi( ultoa_append::@1/(dword) ultoa_append::value#2 ) - (byte*) ultoa_append::buffer#1 ← phi( ultoa_append::@1/(byte*) ultoa_append::buffer#2 ) - (byte) ultoa_append::digit#3 ← phi( ultoa_append::@1/(byte) ultoa_append::digit#4 ) - *((byte*) ultoa_append::buffer#1) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#3) - (dword) ultoa_append::return#1 ← (dword) ultoa_append::value#4 - to:ultoa_append::@return -ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3 - (dword) ultoa_append::return#4 ← phi( ultoa_append::@3/(dword) ultoa_append::return#1 ) - (dword) ultoa_append::return#2 ← (dword) ultoa_append::return#4 - return - to:@return -@12: scope:[] from @begin - (byte*) print_screen#0 ← ((byte*)) (number) $400 - (byte*) print_line_cursor#0 ← (byte*) print_screen#0 - (byte*) print_char_cursor#0 ← (byte*) print_line_cursor#0 - to:@38 - -(void()) print_str((byte*) print_str::str) -print_str: scope:[print_str] from print_dword_decimal::@1 print_person::@2 - (byte*) print_char_cursor#41 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#37 print_person::@2/(byte*) print_char_cursor#13 ) - (byte*) print_str::str#5 ← phi( print_dword_decimal::@1/(byte*) print_str::str#1 print_person::@2/(byte*) print_str::str#2 ) - to:print_str::@1 -print_str::@1: scope:[print_str] from print_str print_str::@2 - (byte*) print_char_cursor#35 ← phi( print_str/(byte*) print_char_cursor#41 print_str::@2/(byte*) print_char_cursor#1 ) - (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 ) - (bool~) print_str::$0 ← (number) 0 != *((byte*) print_str::str#3) - 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#18 ← phi( print_str::@1/(byte*) print_char_cursor#35 ) - (byte*) print_str::str#4 ← phi( print_str::@1/(byte*) print_str::str#3 ) - *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#4) - (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 - (byte*) print_str::str#0 ← ++ (byte*) print_str::str#4 - to:print_str::@1 -print_str::@return: scope:[print_str] from print_str::@1 - (byte*) print_char_cursor#19 ← phi( print_str::@1/(byte*) print_char_cursor#35 ) - (byte*) print_char_cursor#2 ← (byte*) print_char_cursor#19 - return - to:@return - -(void()) print_ln() -print_ln: scope:[print_ln] from print_person::@3 - (byte*) print_char_cursor#36 ← phi( print_person::@3/(byte*) print_char_cursor#14 ) - (byte*) print_line_cursor#18 ← phi( print_person::@3/(byte*) print_line_cursor#20 ) - to:print_ln::@1 -print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 - (byte*) print_char_cursor#20 ← phi( print_ln/(byte*) print_char_cursor#36 print_ln::@1/(byte*) print_char_cursor#20 ) - (byte*) print_line_cursor#9 ← phi( print_ln/(byte*) print_line_cursor#18 print_ln::@1/(byte*) print_line_cursor#1 ) - (byte*~) print_ln::$0 ← (byte*) print_line_cursor#9 + (number) $28 - (byte*) print_line_cursor#1 ← (byte*~) print_ln::$0 - (bool~) print_ln::$1 ← (byte*) print_line_cursor#1 < (byte*) print_char_cursor#20 - 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#10 ← phi( print_ln::@1/(byte*) print_line_cursor#1 ) - (byte*) print_char_cursor#3 ← (byte*) print_line_cursor#10 - to:print_ln::@return -print_ln::@return: scope:[print_ln] from print_ln::@2 - (byte*) print_char_cursor#21 ← phi( print_ln::@2/(byte*) print_char_cursor#3 ) - (byte*) print_line_cursor#11 ← phi( print_ln::@2/(byte*) print_line_cursor#10 ) - (byte*) print_line_cursor#2 ← (byte*) print_line_cursor#11 - (byte*) print_char_cursor#4 ← (byte*) print_char_cursor#21 - return - to:@return - -(void()) print_dword_decimal((dword) print_dword_decimal::w) -print_dword_decimal: scope:[print_dword_decimal] from print_person - (byte*) print_char_cursor#42 ← phi( print_person/(byte*) print_char_cursor#39 ) - (dword) print_dword_decimal::w#1 ← phi( print_person/(dword) print_dword_decimal::w#0 ) - (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#1 - (byte*) ultoa::buffer#5 ← (const byte*) decimal_digits_long - (byte) ultoa::radix#0 ← (const byte) DECIMAL - call ultoa - to:print_dword_decimal::@1 -print_dword_decimal::@1: scope:[print_dword_decimal] from print_dword_decimal - (byte*) print_char_cursor#37 ← phi( print_dword_decimal/(byte*) print_char_cursor#42 ) - (byte*) print_str::str#1 ← (const byte*) decimal_digits_long - call print_str - to:print_dword_decimal::@2 -print_dword_decimal::@2: scope:[print_dword_decimal] from print_dword_decimal::@1 - (byte*) print_char_cursor#22 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#2 ) - (byte*) print_char_cursor#5 ← (byte*) print_char_cursor#22 - to:print_dword_decimal::@return -print_dword_decimal::@return: scope:[print_dword_decimal] from print_dword_decimal::@2 - (byte*) print_char_cursor#23 ← phi( print_dword_decimal::@2/(byte*) print_char_cursor#5 ) - (byte*) print_char_cursor#6 ← (byte*) print_char_cursor#23 - return - to:@return - -(void()) print_char((byte) print_char::ch) -print_char: scope:[print_char] from print_person::@1 - (byte*) print_char_cursor#24 ← phi( print_person::@1/(byte*) print_char_cursor#12 ) - (byte) print_char::ch#1 ← phi( print_person::@1/(byte) print_char::ch#0 ) - *((byte*) print_char_cursor#24) ← (byte) print_char::ch#1 - (byte*) print_char_cursor#7 ← ++ (byte*) print_char_cursor#24 - to:print_char::@return -print_char::@return: scope:[print_char] from print_char - (byte*) print_char_cursor#25 ← phi( print_char/(byte*) print_char_cursor#7 ) - (byte*) print_char_cursor#8 ← (byte*) print_char_cursor#25 - return - to:@return + *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) + *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) + to:@1 (void()) main() -main: scope:[main] from @38 - (byte*) print_line_cursor#19 ← phi( @38/(byte*) print_line_cursor#21 ) - (byte*) print_char_cursor#38 ← phi( @38/(byte*) print_char_cursor#40 ) - (dword) print_person::person_id#0 ← (const dword) jesper_id - (byte*) print_person::person_initials#0 ← (const byte*) jesper_initials +main: scope:[main] from @2 + (byte) idx#18 ← phi( @2/(byte) idx#20 ) + (byte) print_person::person_id#0 ← (const byte) jesper_id + (byte*) print_person::person_name#0 ← (const byte*) jesper_name call print_person to:main::@1 main::@1: scope:[main] from main - (byte*) print_line_cursor#12 ← phi( main/(byte*) print_line_cursor#7 ) - (byte*) print_char_cursor#26 ← phi( main/(byte*) print_char_cursor#16 ) - (byte*) print_char_cursor#9 ← (byte*) print_char_cursor#26 - (byte*) print_line_cursor#3 ← (byte*) print_line_cursor#12 - (dword) print_person::person_id#1 ← (const dword) henry_id - (byte*) print_person::person_initials#1 ← (const byte*) henry_initials + (byte) idx#10 ← phi( main/(byte) idx#8 ) + (byte) idx#0 ← (byte) idx#10 + (byte) print_person::person_id#1 ← (const byte) henriette_id + (byte*) print_person::person_name#1 ← (const byte*) henriette_name call print_person to:main::@2 main::@2: scope:[main] from main::@1 - (byte*) print_line_cursor#13 ← phi( main::@1/(byte*) print_line_cursor#7 ) - (byte*) print_char_cursor#27 ← phi( main::@1/(byte*) print_char_cursor#16 ) - (byte*) print_char_cursor#10 ← (byte*) print_char_cursor#27 - (byte*) print_line_cursor#4 ← (byte*) print_line_cursor#13 + (byte) idx#11 ← phi( main::@1/(byte) idx#8 ) + (byte) idx#1 ← (byte) idx#11 to:main::@return main::@return: scope:[main] from main::@2 - (byte*) print_line_cursor#14 ← phi( main::@2/(byte*) print_line_cursor#4 ) - (byte*) print_char_cursor#28 ← phi( main::@2/(byte*) print_char_cursor#10 ) - (byte*) print_char_cursor#11 ← (byte*) print_char_cursor#28 - (byte*) print_line_cursor#5 ← (byte*) print_line_cursor#14 + (byte) idx#12 ← phi( main::@2/(byte) idx#1 ) + (byte) idx#2 ← (byte) idx#12 return to:@return +@1: scope:[] from @begin + (byte) idx#3 ← (byte) 0 + to:@2 -(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 - (byte*) print_line_cursor#24 ← phi( main/(byte*) print_line_cursor#19 main::@1/(byte*) print_line_cursor#3 ) - (byte*) print_person::person_initials#4 ← phi( main/(byte*) print_person::person_initials#0 main::@1/(byte*) print_person::person_initials#1 ) - (byte*) print_char_cursor#39 ← phi( main/(byte*) print_char_cursor#38 main::@1/(byte*) print_char_cursor#9 ) - (dword) print_person::person_id#2 ← phi( main/(dword) print_person::person_id#0 main::@1/(dword) print_person::person_id#1 ) - (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 - call print_dword_decimal + (byte*) print_person::person_name#4 ← phi( main/(byte*) print_person::person_name#0 main::@1/(byte*) print_person::person_name#1 ) + (byte) idx#13 ← phi( main/(byte) idx#18 main::@1/(byte) idx#0 ) + (byte) print_person::person_id#2 ← phi( main/(byte) print_person::person_id#0 main::@1/(byte) print_person::person_id#1 ) + *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) + (byte) idx#4 ← ++ (byte) idx#13 + *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' + (byte) idx#5 ← ++ (byte) idx#4 + (byte) print_person::i#0 ← (byte) 0 to:print_person::@1 -print_person::@1: scope:[print_person] from print_person - (byte*) print_line_cursor#23 ← phi( print_person/(byte*) print_line_cursor#24 ) - (byte*) print_person::person_initials#3 ← phi( print_person/(byte*) print_person::person_initials#4 ) - (byte*) print_char_cursor#29 ← phi( print_person/(byte*) print_char_cursor#6 ) - (byte*) print_char_cursor#12 ← (byte*) print_char_cursor#29 - (byte) print_char::ch#0 ← (byte) ' ' - call print_char - to:print_person::@2 -print_person::@2: scope:[print_person] from print_person::@1 - (byte*) print_line_cursor#22 ← phi( print_person::@1/(byte*) print_line_cursor#23 ) - (byte*) print_person::person_initials#2 ← phi( print_person::@1/(byte*) print_person::person_initials#3 ) - (byte*) print_char_cursor#30 ← phi( print_person::@1/(byte*) print_char_cursor#8 ) - (byte*) print_char_cursor#13 ← (byte*) print_char_cursor#30 - (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 - call print_str +print_person::@1: scope:[print_person] from print_person print_person::@2 + (byte) idx#19 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 ) + (byte) print_person::i#2 ← phi( print_person/(byte) print_person::i#0 print_person::@2/(byte) print_person::i#1 ) + (byte*) print_person::person_name#2 ← phi( print_person/(byte*) print_person::person_name#4 print_person::@2/(byte*) print_person::person_name#3 ) + (bool~) print_person::$0 ← (number) 0 != *((byte*) print_person::person_name#2 + (byte) print_person::i#2) + if((bool~) print_person::$0) goto print_person::@2 to:print_person::@3 -print_person::@3: scope:[print_person] from print_person::@2 - (byte*) print_line_cursor#20 ← phi( print_person::@2/(byte*) print_line_cursor#22 ) - (byte*) print_char_cursor#31 ← phi( print_person::@2/(byte*) print_char_cursor#2 ) - (byte*) print_char_cursor#14 ← (byte*) print_char_cursor#31 - call print_ln - to:print_person::@4 -print_person::@4: scope:[print_person] from print_person::@3 - (byte*) print_char_cursor#32 ← phi( print_person::@3/(byte*) print_char_cursor#4 ) - (byte*) print_line_cursor#15 ← phi( print_person::@3/(byte*) print_line_cursor#2 ) - (byte*) print_line_cursor#6 ← (byte*) print_line_cursor#15 - (byte*) print_char_cursor#15 ← (byte*) print_char_cursor#32 +print_person::@2: scope:[print_person] from print_person::@1 + (byte) idx#14 ← phi( print_person::@1/(byte) idx#19 ) + (byte) print_person::i#3 ← phi( print_person::@1/(byte) print_person::i#2 ) + (byte*) print_person::person_name#3 ← phi( print_person::@1/(byte*) print_person::person_name#2 ) + *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#3 + (byte) print_person::i#3) + (byte) idx#6 ← ++ (byte) idx#14 + (byte) print_person::i#1 ← ++ (byte) print_person::i#3 + to:print_person::@1 +print_person::@3: scope:[print_person] from print_person::@1 + (byte) idx#15 ← phi( print_person::@1/(byte) idx#19 ) + *((const byte*) SCREEN + (byte) idx#15) ← (byte) ' ' + (byte) idx#7 ← ++ (byte) idx#15 to:print_person::@return -print_person::@return: scope:[print_person] from print_person::@4 - (byte*) print_line_cursor#16 ← phi( print_person::@4/(byte*) print_line_cursor#6 ) - (byte*) print_char_cursor#33 ← phi( print_person::@4/(byte*) print_char_cursor#15 ) - (byte*) print_char_cursor#16 ← (byte*) print_char_cursor#33 - (byte*) print_line_cursor#7 ← (byte*) print_line_cursor#16 +print_person::@return: scope:[print_person] from print_person::@3 + (byte) idx#16 ← phi( print_person::@3/(byte) idx#7 ) + (byte) idx#8 ← (byte) idx#16 return to:@return -@38: scope:[] from @12 - (byte*) print_line_cursor#21 ← phi( @12/(byte*) print_line_cursor#0 ) - (byte*) print_char_cursor#40 ← phi( @12/(byte*) print_char_cursor#0 ) +@2: scope:[] from @1 + (byte) idx#20 ← phi( @1/(byte) idx#3 ) call main - to:@39 -@39: scope:[] from @38 - (byte*) print_line_cursor#17 ← phi( @38/(byte*) print_line_cursor#5 ) - (byte*) print_char_cursor#34 ← phi( @38/(byte*) print_char_cursor#11 ) - (byte*) print_char_cursor#17 ← (byte*) print_char_cursor#34 - (byte*) print_line_cursor#8 ← (byte*) print_line_cursor#17 + to:@3 +@3: scope:[] from @2 + (byte) idx#17 ← phi( @2/(byte) idx#2 ) + (byte) idx#9 ← (byte) idx#17 to:@end -@end: scope:[] from @39 +@end: scope:[] from @3 SYMBOL TABLE SSA -(label) @12 -(label) @38 -(label) @39 +(const byte*) $0[(number) $40] = (string) "jesper" +(const byte*) $1[(number) $40] = (string) "henriette" +(label) @1 +(label) @2 +(label) @3 (label) @begin (label) @end -(const byte) BINARY = (number) 2 -(const byte) DECIMAL = (number) $a -(const byte*) DIGITS = (string) "0123456789abcdef"z -(const byte) HEXADECIMAL = (number) $10 -(const byte) OCTAL = (number) 8 -(dword) Person::id -(const byte*) Person::initials = { fill( 3, 0) } -(const byte) RADIX::BINARY = (number) 2 -(const byte) RADIX::DECIMAL = (number) $a -(const byte) RADIX::HEXADECIMAL = (number) $10 -(const byte) RADIX::OCTAL = (number) 8 -(const dword*) RADIX_BINARY_VALUES_LONG = { (dword)(number) $80000000, (dword)(number) $40000000, (dword)(number) $20000000, (dword)(number) $10000000, (dword)(number) $8000000, (dword)(number) $4000000, (dword)(number) $2000000, (dword)(number) $1000000, (dword)(number) $800000, (dword)(number) $400000, (dword)(number) $200000, (dword)(number) $100000, (dword)(number) $80000, (dword)(number) $40000, (dword)(number) $20000, (dword)(number) $10000, (dword)(number) $8000, (dword)(number) $4000, (dword)(number) $2000, (dword)(number) $1000, (dword)(number) $800, (dword)(number) $400, (dword)(number) $200, (dword)(number) $100, (dword)(number) $80, (dword)(number) $40, (dword)(number) $20, (dword)(number) $10, (dword)(number) 8, (dword)(number) 4, (dword)(number) 2 } -(const dword*) RADIX_DECIMAL_VALUES_LONG = { (dword)(number) $3b9aca00, (dword)(number) $5f5e100, (dword)(number) $989680, (dword)(number) $f4240, (dword)(number) $186a0, (dword)(number) $2710, (dword)(number) $3e8, (dword)(number) $64, (dword)(number) $a } -(const dword*) RADIX_HEXADECIMAL_VALUES_LONG = { (dword)(number) $10000000, (dword)(number) $1000000, (dword)(number) $100000, (dword)(number) $10000, (dword)(number) $1000, (dword)(number) $100, (dword)(number) $10 } -(const dword*) RADIX_OCTAL_VALUES_LONG = { (dword)(number) $40000000, (dword)(number) $8000000, (dword)(number) $1000000, (dword)(number) $200000, (dword)(number) $40000, (dword)(number) $8000, (dword)(number) $1000, (dword)(number) $200, (dword)(number) $40, (dword)(number) 8 } -(const byte) SIZEOF_DWORD = (byte) 4 -(const byte*) decimal_digits_long = { fill( $b, 0) } -(const dword) henry_id = (dword) $4466d -(const byte*) henry_initials = (string) "hg" -(const dword) jesper_id = (dword) $1b244 -(const byte*) jesper_initials = (string) "jg" +(const byte*) DIGIT[] = (string) "0123456789" +(byte) Person::id +(const byte*) Person::name[(number) $40] = { fill( $40, 0) } +(const byte*) SCREEN = (byte*)(number) $400 +(const byte) henriette_id = (byte) 7 +(const byte*) henriette_name[(number) $40] = { fill( $40, 0) } +(byte) idx +(byte) idx#0 +(byte) idx#1 +(byte) idx#10 +(byte) idx#11 +(byte) idx#12 +(byte) idx#13 +(byte) idx#14 +(byte) idx#15 +(byte) idx#16 +(byte) idx#17 +(byte) idx#18 +(byte) idx#19 +(byte) idx#2 +(byte) idx#20 +(byte) idx#3 +(byte) idx#4 +(byte) idx#5 +(byte) idx#6 +(byte) idx#7 +(byte) idx#8 +(byte) idx#9 +(const byte) jesper_id = (byte) 4 +(const byte*) jesper_name[(number) $40] = { fill( $40, 0) } (void()) main() (label) main::@1 (label) main::@2 (label) main::@return -(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_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#5 -(byte*) print_char_cursor#6 -(byte*) print_char_cursor#7 -(byte*) print_char_cursor#8 -(byte*) print_char_cursor#9 -(void()) print_dword_decimal((dword) print_dword_decimal::w) -(label) print_dword_decimal::@1 -(label) print_dword_decimal::@2 -(label) print_dword_decimal::@return -(dword) print_dword_decimal::w -(dword) print_dword_decimal::w#0 -(dword) print_dword_decimal::w#1 -(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#3 -(byte*) print_line_cursor#4 -(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_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) +(bool~) print_person::$0 (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 -(label) print_person::@4 (label) print_person::@return +(byte) print_person::i +(byte) print_person::i#0 +(byte) print_person::i#1 +(byte) print_person::i#2 +(byte) print_person::i#3 (struct Person) print_person::person -(dword) print_person::person_id -(dword) print_person::person_id#0 -(dword) print_person::person_id#1 -(dword) print_person::person_id#2 -(const byte*) print_person::person_initials -(byte*) print_person::person_initials#0 -(byte*) print_person::person_initials#1 -(byte*) print_person::person_initials#2 -(byte*) print_person::person_initials#3 -(byte*) print_person::person_initials#4 -(byte*) print_screen -(byte*) print_screen#0 -(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 -(byte*) print_str::str#5 -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -(bool~) ultoa::$0 -(bool~) ultoa::$1 -(dword~) ultoa::$10 -(byte~) ultoa::$11 -(bool~) ultoa::$2 -(bool~) ultoa::$3 -(byte~) ultoa::$4 -(number~) ultoa::$5 -(bool~) ultoa::$6 -(bool~) ultoa::$7 -(bool~) ultoa::$8 -(bool~) ultoa::$9 -(label) ultoa::@1 -(label) ultoa::@10 -(label) ultoa::@11 -(label) ultoa::@12 -(label) ultoa::@18 -(label) ultoa::@19 -(label) ultoa::@2 -(label) ultoa::@20 -(label) ultoa::@21 -(label) ultoa::@24 -(label) ultoa::@26 -(label) ultoa::@3 -(label) ultoa::@4 -(label) ultoa::@8 -(label) ultoa::@9 -(label) ultoa::@return -(byte*) ultoa::buffer -(byte*) ultoa::buffer#0 -(byte*) ultoa::buffer#1 -(byte*) ultoa::buffer#10 -(byte*) ultoa::buffer#11 -(byte*) ultoa::buffer#12 -(byte*) ultoa::buffer#13 -(byte*) ultoa::buffer#14 -(byte*) ultoa::buffer#15 -(byte*) ultoa::buffer#16 -(byte*) ultoa::buffer#17 -(byte*) ultoa::buffer#18 -(byte*) ultoa::buffer#19 -(byte*) ultoa::buffer#2 -(byte*) ultoa::buffer#20 -(byte*) ultoa::buffer#21 -(byte*) ultoa::buffer#3 -(byte*) ultoa::buffer#4 -(byte*) ultoa::buffer#5 -(byte*) ultoa::buffer#6 -(byte*) ultoa::buffer#7 -(byte*) ultoa::buffer#8 -(byte*) ultoa::buffer#9 -(byte) ultoa::digit -(byte) ultoa::digit#0 -(byte) ultoa::digit#1 -(byte) ultoa::digit#2 -(byte) ultoa::digit#3 -(byte) ultoa::digit#4 -(byte) ultoa::digit#5 -(byte) ultoa::digit#6 -(dword) ultoa::digit_value -(dword) ultoa::digit_value#0 -(dword) ultoa::digit_value#1 -(dword*) ultoa::digit_values -(dword*) ultoa::digit_values#0 -(dword*) ultoa::digit_values#1 -(dword*) ultoa::digit_values#10 -(dword*) ultoa::digit_values#2 -(dword*) ultoa::digit_values#3 -(dword*) ultoa::digit_values#4 -(dword*) ultoa::digit_values#5 -(dword*) ultoa::digit_values#6 -(dword*) ultoa::digit_values#7 -(dword*) ultoa::digit_values#8 -(dword*) ultoa::digit_values#9 -(byte) ultoa::max_digits -(byte) ultoa::max_digits#0 -(byte) ultoa::max_digits#1 -(byte) ultoa::max_digits#10 -(byte) ultoa::max_digits#2 -(byte) ultoa::max_digits#3 -(byte) ultoa::max_digits#4 -(byte) ultoa::max_digits#5 -(byte) ultoa::max_digits#6 -(byte) ultoa::max_digits#7 -(byte) ultoa::max_digits#8 -(byte) ultoa::max_digits#9 -(byte) ultoa::radix -(byte) ultoa::radix#0 -(byte) ultoa::radix#1 -(byte) ultoa::radix#2 -(byte) ultoa::radix#3 -(byte) ultoa::radix#4 -(byte) ultoa::started -(byte) ultoa::started#0 -(byte) ultoa::started#1 -(byte) ultoa::started#2 -(byte) ultoa::started#3 -(byte) ultoa::started#4 -(dword) ultoa::value -(dword) ultoa::value#0 -(dword) ultoa::value#1 -(dword) ultoa::value#10 -(dword) ultoa::value#11 -(dword) ultoa::value#12 -(dword) ultoa::value#13 -(dword) ultoa::value#14 -(dword) ultoa::value#15 -(dword) ultoa::value#2 -(dword) ultoa::value#3 -(dword) ultoa::value#4 -(dword) ultoa::value#5 -(dword) ultoa::value#6 -(dword) ultoa::value#7 -(dword) ultoa::value#8 -(dword) ultoa::value#9 -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -(bool~) ultoa_append::$0 -(label) ultoa_append::@1 -(label) ultoa_append::@2 -(label) ultoa_append::@3 -(label) ultoa_append::@return -(byte*) ultoa_append::buffer -(byte*) ultoa_append::buffer#0 -(byte*) ultoa_append::buffer#1 -(byte*) ultoa_append::buffer#2 -(byte*) ultoa_append::buffer#3 -(byte*) ultoa_append::buffer#4 -(byte) ultoa_append::digit -(byte) ultoa_append::digit#0 -(byte) ultoa_append::digit#1 -(byte) ultoa_append::digit#2 -(byte) ultoa_append::digit#3 -(byte) ultoa_append::digit#4 -(dword) ultoa_append::return -(dword) ultoa_append::return#0 -(dword) ultoa_append::return#1 -(dword) ultoa_append::return#2 -(dword) ultoa_append::return#3 -(dword) ultoa_append::return#4 -(dword) ultoa_append::sub -(dword) ultoa_append::sub#0 -(dword) ultoa_append::sub#1 -(dword) ultoa_append::sub#2 -(dword) ultoa_append::sub#3 -(dword) ultoa_append::value -(dword) ultoa_append::value#0 -(dword) ultoa_append::value#1 -(dword) ultoa_append::value#2 -(dword) ultoa_append::value#3 -(dword) ultoa_append::value#4 -(dword) ultoa_append::value#5 +(byte) print_person::person_id +(byte) print_person::person_id#0 +(byte) print_person::person_id#1 +(byte) print_person::person_id#2 +(byte*) print_person::person_name +(byte*) print_person::person_name#0 +(byte*) print_person::person_name#1 +(byte*) print_person::person_name#2 +(byte*) print_person::person_name#3 +(byte*) print_person::person_name#4 -Adding number conversion cast (unumber) $a in (byte) ultoa::max_digits#1 ← (number) $a -Adding number conversion cast (unumber) 8 in (byte) ultoa::max_digits#2 ← (number) 8 -Adding number conversion cast (unumber) $b in (byte) ultoa::max_digits#3 ← (number) $b -Adding number conversion cast (unumber) $20 in (byte) ultoa::max_digits#4 ← (number) $20 -Adding number conversion cast (unumber) 0 in *((byte*) ultoa::buffer#2) ← (number) 0 -Adding number conversion cast (unumber) 0 in (byte) ultoa::started#0 ← (number) 0 -Adding number conversion cast (unumber) 0 in (byte) ultoa::digit#0 ← (number) 0 -Adding number conversion cast (unumber) 1 in (number~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (number) 1 -Adding number conversion cast (unumber) ultoa::$5 in (number~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (unumber)(number) 1 -Adding number conversion cast (unumber) 0 in *((byte*) ultoa::buffer#3) ← (number) 0 -Adding number conversion cast (unumber) 1 in (byte) ultoa::started#1 ← (number) 1 -Adding number conversion cast (unumber) 0 in (byte) ultoa_append::digit#0 ← (number) 0 -Adding number conversion cast (unumber) 0 in (bool~) print_str::$0 ← (number) 0 != *((byte*) print_str::str#3) -Adding number conversion cast (unumber) $28 in (byte*~) print_ln::$0 ← (byte*) print_line_cursor#9 + (number) $28 +Adding number conversion cast (unumber) 0 in (bool~) print_person::$0 ← (number) 0 != *((byte*) print_person::person_name#2 + (byte) print_person::i#2) Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast (byte) ultoa::max_digits#1 ← (unumber)(number) $a -Inlining cast (byte) ultoa::max_digits#2 ← (unumber)(number) 8 -Inlining cast (byte) ultoa::max_digits#3 ← (unumber)(number) $b -Inlining cast (byte) ultoa::max_digits#4 ← (unumber)(number) $20 -Inlining cast *((byte*) ultoa::buffer#2) ← (unumber)(number) 0 -Inlining cast (byte) ultoa::started#0 ← (unumber)(number) 0 -Inlining cast (byte) ultoa::digit#0 ← (unumber)(number) 0 -Inlining cast (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#3 -Inlining cast *((byte*) ultoa::buffer#3) ← (unumber)(number) 0 -Inlining cast (byte) ultoa::started#1 ← (unumber)(number) 1 -Inlining cast (byte) ultoa_append::digit#0 ← (unumber)(number) 0 -Inlining cast (byte*) print_screen#0 ← (byte*)(number) $400 -Successful SSA optimization Pass2InlineCast -Simplifying constant integer cast $80000000 -Simplifying constant integer cast $40000000 -Simplifying constant integer cast $20000000 -Simplifying constant integer cast $10000000 -Simplifying constant integer cast $8000000 -Simplifying constant integer cast $4000000 -Simplifying constant integer cast $2000000 -Simplifying constant integer cast $1000000 -Simplifying constant integer cast $800000 -Simplifying constant integer cast $400000 -Simplifying constant integer cast $200000 -Simplifying constant integer cast $100000 -Simplifying constant integer cast $80000 -Simplifying constant integer cast $40000 -Simplifying constant integer cast $20000 -Simplifying constant integer cast $10000 -Simplifying constant integer cast $8000 -Simplifying constant integer cast $4000 -Simplifying constant integer cast $2000 -Simplifying constant integer cast $1000 -Simplifying constant integer cast $800 -Simplifying constant integer cast $400 -Simplifying constant integer cast $200 -Simplifying constant integer cast $100 -Simplifying constant integer cast $80 -Simplifying constant integer cast $40 -Simplifying constant integer cast $20 -Simplifying constant integer cast $10 -Simplifying constant integer cast 8 -Simplifying constant integer cast 4 -Simplifying constant integer cast 2 -Simplifying constant integer cast $40000000 -Simplifying constant integer cast $8000000 -Simplifying constant integer cast $1000000 -Simplifying constant integer cast $200000 -Simplifying constant integer cast $40000 -Simplifying constant integer cast $8000 -Simplifying constant integer cast $1000 -Simplifying constant integer cast $200 -Simplifying constant integer cast $40 -Simplifying constant integer cast 8 -Simplifying constant integer cast $3b9aca00 -Simplifying constant integer cast $5f5e100 -Simplifying constant integer cast $989680 -Simplifying constant integer cast $f4240 -Simplifying constant integer cast $186a0 -Simplifying constant integer cast $2710 -Simplifying constant integer cast $3e8 -Simplifying constant integer cast $64 -Simplifying constant integer cast $a -Simplifying constant integer cast $10000000 -Simplifying constant integer cast $1000000 -Simplifying constant integer cast $100000 -Simplifying constant integer cast $10000 -Simplifying constant integer cast $1000 -Simplifying constant integer cast $100 -Simplifying constant integer cast $10 -Simplifying constant integer cast $a -Simplifying constant integer cast 8 -Simplifying constant integer cast $b -Simplifying constant integer cast $20 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 1 -Simplifying constant integer cast 0 -Simplifying constant integer cast 1 -Simplifying constant integer cast 0 Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 0 -Simplifying constant integer cast $28 -Successful SSA optimization PassNCastSimplification -Finalized unsigned number type (byte) $a -Finalized unsigned number type (byte) 8 -Finalized unsigned number type (byte) $b -Finalized unsigned number type (byte) $20 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 1 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 1 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) $28 -Successful SSA optimization PassNFinalizeNumberTypeConversions -Inferred type updated to byte in (unumber~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (byte) 1 -Alias (dword) ultoa::value#10 = (dword) ultoa::value#8 (dword) ultoa::value#12 (dword) ultoa::value#13 (dword) ultoa::value#9 (dword) ultoa::value#14 (dword) ultoa::value#15 (dword) ultoa::value#11 -Alias (byte*) ultoa::buffer#10 = (byte*) ultoa::buffer#17 (byte*) ultoa::buffer#21 (byte*) ultoa::buffer#16 (byte*) ultoa::buffer#18 (byte*) ultoa::buffer#13 (byte*) ultoa::buffer#19 (byte*) ultoa::buffer#20 (byte*) ultoa::buffer#6 -Alias (byte) ultoa::radix#1 = (byte) ultoa::radix#2 (byte) ultoa::radix#3 (byte) ultoa::radix#4 -Alias (byte) ultoa::digit#2 = (byte) ultoa::digit#3 (byte) ultoa::digit#6 (byte) ultoa::digit#5 -Alias (dword*) ultoa::digit_values#10 = (dword*) ultoa::digit_values#5 (dword*) ultoa::digit_values#6 (dword*) ultoa::digit_values#9 -Alias (dword) ultoa::value#2 = (dword) ultoa::value#5 (dword) ultoa::value#3 (dword) ultoa::value#4 -Alias (byte) ultoa::started#2 = (byte) ultoa::started#3 -Alias (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#12 (byte*) ultoa::buffer#7 (byte*) ultoa::buffer#8 (byte*) ultoa::buffer#9 -Alias (byte) ultoa::max_digits#10 = (byte) ultoa::max_digits#8 (byte) ultoa::max_digits#5 (byte) ultoa::max_digits#9 -Alias (dword) ultoa::digit_value#0 = (dword) ultoa::digit_value#1 -Alias (dword) ultoa_append::return#0 = (dword) ultoa_append::return#3 -Alias (dword) ultoa::value#0 = (dword~) ultoa::$10 -Alias (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#4 (byte) ultoa_append::digit#3 -Alias (dword) ultoa_append::value#2 = (dword) ultoa_append::value#3 (dword) ultoa_append::value#4 (dword) ultoa_append::return#1 (dword) ultoa_append::return#4 (dword) ultoa_append::return#2 -Alias (dword) ultoa_append::sub#1 = (dword) ultoa_append::sub#2 -Alias (byte*) ultoa_append::buffer#1 = (byte*) ultoa_append::buffer#4 (byte*) ultoa_append::buffer#2 -Alias (byte*) print_char_cursor#0 = (byte*) print_line_cursor#0 (byte*) print_screen#0 (byte*) print_char_cursor#40 (byte*) print_line_cursor#21 -Alias (byte*) print_str::str#3 = (byte*) print_str::str#4 -Alias (byte*) print_char_cursor#18 = (byte*) print_char_cursor#35 (byte*) print_char_cursor#19 (byte*) print_char_cursor#2 -Alias (byte*) print_line_cursor#1 = (byte*~) print_ln::$0 (byte*) print_line_cursor#10 (byte*) print_char_cursor#3 (byte*) print_line_cursor#11 (byte*) print_char_cursor#21 (byte*) print_line_cursor#2 (byte*) print_char_cursor#4 -Alias (byte*) print_char_cursor#37 = (byte*) print_char_cursor#42 -Alias (byte*) print_char_cursor#22 = (byte*) print_char_cursor#5 (byte*) print_char_cursor#23 (byte*) print_char_cursor#6 -Alias (byte*) print_char_cursor#25 = (byte*) print_char_cursor#7 (byte*) print_char_cursor#8 -Alias (byte*) print_char_cursor#26 = (byte*) print_char_cursor#9 -Alias (byte*) print_line_cursor#12 = (byte*) print_line_cursor#3 -Alias (byte*) print_char_cursor#10 = (byte*) print_char_cursor#27 (byte*) print_char_cursor#28 (byte*) print_char_cursor#11 -Alias (byte*) print_line_cursor#13 = (byte*) print_line_cursor#4 (byte*) print_line_cursor#14 (byte*) print_line_cursor#5 -Alias (byte*) print_person::person_initials#2 = (byte*) print_person::person_initials#3 (byte*) print_person::person_initials#4 -Alias (byte*) print_line_cursor#20 = (byte*) print_line_cursor#23 (byte*) print_line_cursor#24 (byte*) print_line_cursor#22 -Alias (byte*) print_char_cursor#12 = (byte*) print_char_cursor#29 -Alias (byte*) print_char_cursor#13 = (byte*) print_char_cursor#30 -Alias (byte*) print_char_cursor#14 = (byte*) print_char_cursor#31 -Alias (byte*) print_line_cursor#15 = (byte*) print_line_cursor#6 (byte*) print_line_cursor#16 (byte*) print_line_cursor#7 -Alias (byte*) print_char_cursor#15 = (byte*) print_char_cursor#32 (byte*) print_char_cursor#33 (byte*) print_char_cursor#16 -Alias (byte*) print_char_cursor#17 = (byte*) print_char_cursor#34 -Alias (byte*) print_line_cursor#17 = (byte*) print_line_cursor#8 -Successful SSA optimization Pass2AliasElimination -Alias (dword) ultoa::value#10 = (dword) ultoa::value#7 -Alias (byte*) ultoa::buffer#10 = (byte*) ultoa::buffer#15 -Alias (byte) ultoa::digit#2 = (byte) ultoa::digit#4 -Alias (byte) ultoa::max_digits#10 = (byte) ultoa::max_digits#6 -Alias (dword*) ultoa::digit_values#10 = (dword*) ultoa::digit_values#7 -Successful SSA optimization Pass2AliasElimination -Identical Phi Values (byte) ultoa::radix#1 (byte) ultoa::radix#0 -Identical Phi Values (dword) ultoa::value#10 (dword) ultoa::value#1 -Identical Phi Values (byte*) ultoa::buffer#10 (byte*) ultoa::buffer#5 -Identical Phi Values (byte) ultoa::max_digits#10 (byte) ultoa::max_digits#7 -Identical Phi Values (dword*) ultoa::digit_values#10 (dword*) ultoa::digit_values#8 -Identical Phi Values (dword) ultoa_append::value#5 (dword) ultoa_append::value#0 -Identical Phi Values (dword) ultoa_append::sub#3 (dword) ultoa_append::sub#0 -Identical Phi Values (byte*) ultoa_append::buffer#3 (byte*) ultoa_append::buffer#0 -Identical Phi Values (dword) ultoa_append::sub#1 (dword) ultoa_append::sub#3 -Identical Phi Values (byte*) ultoa_append::buffer#1 (byte*) ultoa_append::buffer#3 -Identical Phi Values (byte*) print_line_cursor#18 (byte*) print_line_cursor#20 -Identical Phi Values (byte*) print_char_cursor#36 (byte*) print_char_cursor#14 -Identical Phi Values (byte*) print_char_cursor#20 (byte*) print_char_cursor#36 -Identical Phi Values (dword) print_dword_decimal::w#1 (dword) print_dword_decimal::w#0 -Identical Phi Values (byte*) print_char_cursor#37 (byte*) print_char_cursor#39 -Identical Phi Values (byte*) print_char_cursor#22 (byte*) print_char_cursor#18 -Identical Phi Values (byte) print_char::ch#1 (byte) print_char::ch#0 -Identical Phi Values (byte*) print_char_cursor#24 (byte*) print_char_cursor#12 -Identical Phi Values (byte*) print_char_cursor#38 (byte*) print_char_cursor#0 -Identical Phi Values (byte*) print_line_cursor#19 (byte*) print_char_cursor#0 -Identical Phi Values (byte*) print_char_cursor#26 (byte*) print_char_cursor#15 -Identical Phi Values (byte*) print_line_cursor#12 (byte*) print_line_cursor#15 -Identical Phi Values (byte*) print_char_cursor#10 (byte*) print_char_cursor#15 -Identical Phi Values (byte*) print_line_cursor#13 (byte*) print_line_cursor#15 -Identical Phi Values (byte*) print_char_cursor#12 (byte*) print_char_cursor#22 -Identical Phi Values (byte*) print_char_cursor#13 (byte*) print_char_cursor#25 -Identical Phi Values (byte*) print_char_cursor#14 (byte*) print_char_cursor#18 -Identical Phi Values (byte*) print_line_cursor#15 (byte*) print_line_cursor#1 -Identical Phi Values (byte*) print_char_cursor#15 (byte*) print_line_cursor#1 -Identical Phi Values (byte*) print_char_cursor#17 (byte*) print_char_cursor#10 -Identical Phi Values (byte*) print_line_cursor#17 (byte*) print_line_cursor#13 -Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition (bool~) ultoa::$0 [4] if((byte) ultoa::radix#0==(const byte) DECIMAL) goto ultoa::@1 -Simple Condition (bool~) ultoa::$1 [10] if((byte) ultoa::radix#0==(const byte) HEXADECIMAL) goto ultoa::@2 -Simple Condition (bool~) ultoa::$2 [16] if((byte) ultoa::radix#0==(const byte) OCTAL) goto ultoa::@3 -Simple Condition (bool~) ultoa::$3 [22] if((byte) ultoa::radix#0==(const byte) BINARY) goto ultoa::@4 -Simple Condition (bool~) ultoa::$6 [41] if((byte) ultoa::digit#2<(byte~) ultoa::$5) goto ultoa::@19 -Simple Condition (bool~) ultoa_append::$0 [71] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -Simple Condition (bool~) print_str::$0 [87] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -Simple Condition (bool~) print_ln::$1 [100] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 -Successful SSA optimization Pass2ConditionalJumpSimplification -Rewriting ! if()-condition to reversed if() [47] (bool~) ultoa::$9 ← ! (bool~) ultoa::$8 -Rewriting || if()-condition to two if()s [46] (bool~) ultoa::$8 ← (byte) ultoa::started#2 || (bool~) ultoa::$7 -Successful SSA optimization Pass2ConditionalAndOrRewriting -Warning! Adding boolean cast to non-boolean condition (byte) ultoa::started#2 -Constant (const byte) ultoa::max_digits#0 = 0 -Constant (const dword*) ultoa::digit_values#0 = (dword*) 0 -Constant (const byte) ultoa::max_digits#1 = $a -Constant (const dword*) ultoa::digit_values#1 = RADIX_DECIMAL_VALUES_LONG -Constant (const byte) ultoa::max_digits#2 = 8 -Constant (const dword*) ultoa::digit_values#2 = RADIX_HEXADECIMAL_VALUES_LONG -Constant (const byte) ultoa::max_digits#3 = $b -Constant (const dword*) ultoa::digit_values#3 = RADIX_OCTAL_VALUES_LONG -Constant (const byte) ultoa::max_digits#4 = $20 -Constant (const dword*) ultoa::digit_values#4 = RADIX_BINARY_VALUES_LONG -Constant (const byte) ultoa::started#0 = 0 -Constant (const byte) ultoa::digit#0 = 0 -Constant (const byte) ultoa::started#1 = 1 -Constant (const byte) ultoa_append::digit#0 = 0 -Constant (const byte*) print_char_cursor#0 = (byte*) 1024 -Constant (const byte*) ultoa::buffer#5 = decimal_digits_long -Constant (const byte) ultoa::radix#0 = DECIMAL -Constant (const byte*) print_str::str#1 = decimal_digits_long -Constant (const dword) print_person::person_id#0 = jesper_id -Constant (const byte*) print_person::person_initials#0 = jesper_initials -Constant (const dword) print_person::person_id#1 = henry_id -Constant (const byte*) print_person::person_initials#1 = henry_initials -Constant (const byte) print_char::ch#0 = ' ' -Successful SSA optimization Pass2ConstantIdentification -if() condition always true - replacing block destination [4] if((const byte) ultoa::radix#0==(const byte) DECIMAL) goto ultoa::@1 -if() condition always false - eliminating [10] if((const byte) ultoa::radix#0==(const byte) HEXADECIMAL) goto ultoa::@2 -if() condition always false - eliminating [16] if((const byte) ultoa::radix#0==(const byte) OCTAL) goto ultoa::@3 -if() condition always false - eliminating [22] if((const byte) ultoa::radix#0==(const byte) BINARY) goto ultoa::@4 -Successful SSA optimization Pass2ConstantIfs -Eliminating unused constant (const byte) BINARY -Eliminating unused constant (const byte) OCTAL -Eliminating unused constant (const byte) HEXADECIMAL -Eliminating unused constant (const byte) ultoa::max_digits#0 -Eliminating unused constant (const dword*) ultoa::digit_values#0 -Eliminating unused constant (const byte) ultoa::radix#0 -Successful SSA optimization PassNEliminateUnusedVars -Eliminating unused constant (const byte) DECIMAL -Successful SSA optimization PassNEliminateUnusedVars -Eliminating variable (byte*) ultoa::buffer#0 from unused block ultoa::@12 -Eliminating variable (byte*) ultoa::buffer#1 from unused block ultoa::@12 -Eliminating variable (byte*) ultoa::buffer#2 from unused block ultoa::@12 -Removing unused block ultoa::@9 -Removing PHI-reference to removed block (ultoa::@2) in block ultoa::@8 -Removing PHI-reference to removed block (ultoa::@2) in block ultoa::@8 -Removing unused block ultoa::@2 -Removing unused block ultoa::@10 -Removing PHI-reference to removed block (ultoa::@3) in block ultoa::@8 -Removing PHI-reference to removed block (ultoa::@3) in block ultoa::@8 -Removing unused block ultoa::@3 -Removing unused block ultoa::@11 -Removing PHI-reference to removed block (ultoa::@4) in block ultoa::@8 -Removing PHI-reference to removed block (ultoa::@4) in block ultoa::@8 -Removing unused block ultoa::@4 -Removing unused block ultoa::@12 -Successful SSA optimization Pass2EliminateUnusedBlocks -Adding number conversion cast (unumber) 0 in (bool~) ultoa::$12 ← (number) 0 != (byte) ultoa::started#2 -Successful SSA optimization PassNAddNumberTypeConversions -Simplifying constant integer cast 0 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions -Identical Phi Values (byte) ultoa::max_digits#7 (const byte) ultoa::max_digits#1 -Identical Phi Values (dword*) ultoa::digit_values#8 (const dword*) ultoa::digit_values#1 +Alias (byte) idx#0 = (byte) idx#10 +Alias (byte) idx#1 = (byte) idx#11 (byte) idx#12 (byte) idx#2 +Alias (byte*) print_person::person_name#2 = (byte*) print_person::person_name#3 +Alias (byte) print_person::i#2 = (byte) print_person::i#3 +Alias (byte) idx#14 = (byte) idx#19 (byte) idx#15 +Alias (byte) idx#16 = (byte) idx#7 (byte) idx#8 +Alias (byte) idx#20 = (byte) idx#3 +Alias (byte) idx#17 = (byte) idx#9 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) idx#18 (byte) idx#20 +Identical Phi Values (byte) idx#0 (byte) idx#16 +Identical Phi Values (byte) idx#1 (byte) idx#16 +Identical Phi Values (byte*) print_person::person_name#2 (byte*) print_person::person_name#4 +Identical Phi Values (byte) idx#17 (byte) idx#1 Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition (bool~) ultoa::$12 [9] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@24 -Simple Condition (bool~) ultoa::$7 [59] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@24 +Simple Condition (bool~) print_person::$0 [25] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 Successful SSA optimization Pass2ConditionalJumpSimplification -Constant right-side identified [3] (byte~) ultoa::$5 ← (const byte) ultoa::max_digits#1 - (byte) 1 -Successful SSA optimization Pass2ConstantRValueConsolidation -Constant (const byte) ultoa::$5 = ultoa::max_digits#1-1 +Constant (const byte) print_person::person_id#0 = jesper_id +Constant (const byte*) print_person::person_name#0 = jesper_name +Constant (const byte) print_person::person_id#1 = henriette_id +Constant (const byte*) print_person::person_name#1 = henriette_name +Constant (const byte) idx#20 = 0 +Constant (const byte) print_person::i#0 = 0 Successful SSA optimization Pass2ConstantIdentification -Eliminating unused constant (const byte) ultoa::max_digits#2 -Eliminating unused constant (const dword*) ultoa::digit_values#2 -Eliminating unused constant (const byte) ultoa::max_digits#3 -Eliminating unused constant (const dword*) ultoa::digit_values#3 -Eliminating unused constant (const byte) ultoa::max_digits#4 -Eliminating unused constant (const dword*) ultoa::digit_values#4 -Successful SSA optimization PassNEliminateUnusedVars -Eliminating unused constant (const dword*) RADIX_BINARY_VALUES_LONG -Eliminating unused constant (const dword*) RADIX_OCTAL_VALUES_LONG -Eliminating unused constant (const dword*) RADIX_HEXADECIMAL_VALUES_LONG -Successful SSA optimization PassNEliminateUnusedVars -Rewriting multiplication to use shift [3] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 * (const byte) SIZEOF_DWORD -Successful SSA optimization Pass2MultiplyToShiftRewriting -Inlining constant with var siblings (const byte) ultoa::started#0 -Inlining constant with var siblings (const byte) ultoa::digit#0 -Inlining constant with var siblings (const byte) ultoa::started#1 -Inlining constant with var siblings (const byte*) ultoa::buffer#5 -Inlining constant with var siblings (const byte) ultoa_append::digit#0 -Inlining constant with var siblings (const byte*) print_str::str#1 -Inlining constant with var siblings (const dword) print_person::person_id#0 -Inlining constant with var siblings (const byte*) print_person::person_initials#0 -Inlining constant with var siblings (const dword) print_person::person_id#1 -Inlining constant with var siblings (const byte*) print_person::person_initials#1 -Inlining constant with var siblings (const byte*) print_char_cursor#0 -Constant inlined print_person::person_initials#1 = (const byte*) henry_initials -Constant inlined ultoa::started#1 = (byte) 1 -Constant inlined print_char_cursor#0 = (byte*) 1024 -Constant inlined ultoa::buffer#5 = (const byte*) decimal_digits_long -Constant inlined print_person::person_id#1 = (const dword) henry_id -Constant inlined print_person::person_id#0 = (const dword) jesper_id -Constant inlined ultoa::$5 = (const byte) ultoa::max_digits#1-(byte) 1 -Constant inlined ultoa::started#0 = (byte) 0 -Constant inlined ultoa::digit#0 = (byte) 0 -Constant inlined ultoa_append::digit#0 = (byte) 0 -Constant inlined ultoa::digit_values#1 = (const dword*) RADIX_DECIMAL_VALUES_LONG -Constant inlined print_str::str#1 = (const byte*) decimal_digits_long -Constant inlined print_person::person_initials#0 = (const byte*) jesper_initials +Inlining constant with var siblings (const byte) print_person::person_id#0 +Inlining constant with var siblings (const byte*) print_person::person_name#0 +Inlining constant with var siblings (const byte) print_person::person_id#1 +Inlining constant with var siblings (const byte*) print_person::person_name#1 +Inlining constant with var siblings (const byte) print_person::i#0 +Inlining constant with var siblings (const byte) idx#20 +Constant inlined idx#20 = (byte) 0 +Constant inlined print_person::person_id#1 = (const byte) henriette_id +Constant inlined print_person::person_id#0 = (const byte) jesper_id +Constant inlined print_person::i#0 = (byte) 0 +Constant inlined print_person::person_name#1 = (const byte*) henriette_name +Constant inlined print_person::person_name#0 = (const byte*) jesper_name Successful SSA optimization Pass2ConstantInlining -Eliminating unused constant (const byte) SIZEOF_DWORD -Successful SSA optimization PassNEliminateUnusedVars -Added new block during phi lifting ultoa::@28(between ultoa::@27 and ultoa::@21) -Added new block during phi lifting print_ln::@3(between print_ln::@1 and print_ln::@1) -Adding NOP phi() at start of @begin -Adding NOP phi() at start of @12 -Adding NOP phi() at start of @38 -Adding NOP phi() at start of @39 +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @3 Adding NOP phi() at start of @end Adding NOP phi() at start of main Adding NOP phi() at start of main::@2 -Adding NOP phi() at start of print_person::@1 -Adding NOP phi() at start of print_person::@3 -Adding NOP phi() at start of print_person::@4 -Adding NOP phi() at start of print_ln::@2 -Adding NOP phi() at start of print_dword_decimal::@2 -Adding NOP phi() at start of ultoa -Adding NOP phi() at start of ultoa::@1 CALL GRAPH -Calls in [] to main:3 -Calls in [main] to print_person:7 print_person:10 -Calls in [print_person] to print_dword_decimal:15 print_char:17 print_str:21 print_ln:23 -Calls in [print_dword_decimal] to ultoa:48 print_str:50 -Calls in [ultoa] to ultoa_append:79 +Calls in [] to main:4 +Calls in [main] to print_person:8 print_person:10 -Created 18 initial phi equivalence classes -Not coalescing [8] print_char_cursor#47 ← print_line_cursor#1 -Coalesced [9] print_line_cursor#27 ← print_line_cursor#1 -Coalesced [19] print_str::str#6 ← print_str::str#2 -Coalesced [20] print_char_cursor#44 ← print_char_cursor#25 -Coalesced [26] print_line_cursor#25 ← print_line_cursor#20 -Coalesced (already) [32] print_line_cursor#26 ← print_line_cursor#1 -Coalesced [34] print_str::str#7 ← print_str::str#5 -Coalesced [35] print_char_cursor#45 ← print_char_cursor#41 -Coalesced [42] print_str::str#8 ← print_str::str#0 -Coalesced [43] print_char_cursor#46 ← print_char_cursor#1 -Coalesced [49] print_char_cursor#43 ← print_char_cursor#39 -Coalesced [55] ultoa::value#17 ← ultoa::value#1 -Coalesced [67] ultoa::value#18 ← ultoa::value#2 -Coalesced [68] ultoa::started#6 ← ultoa::started#2 -Coalesced [69] ultoa::buffer#23 ← ultoa::buffer#11 -Coalesced [72] ultoa::digit#7 ← ultoa::digit#1 -Coalesced (already) [73] ultoa::value#16 ← ultoa::value#6 -Coalesced (already) [74] ultoa::started#5 ← ultoa::started#4 -Coalesced (already) [75] ultoa::buffer#22 ← ultoa::buffer#14 -Coalesced [83] ultoa::value#19 ← ultoa::value#0 -Coalesced [84] ultoa::buffer#24 ← ultoa::buffer#4 -Coalesced [85] ultoa_append::value#6 ← ultoa_append::value#0 -Coalesced [92] ultoa_append::value#7 ← ultoa_append::value#1 -Coalesced [93] ultoa_append::digit#5 ← ultoa_append::digit#1 -Coalesced down to 11 phi equivalence classes -Culled Empty Block (label) @12 -Culled Empty Block (label) @39 +Created 5 initial phi equivalence classes +Coalesced [9] idx#21 ← idx#16 +Coalesced [18] idx#22 ← idx#5 +Coalesced [27] print_person::i#4 ← print_person::i#1 +Coalesced [28] idx#23 ← idx#6 +Coalesced down to 5 phi equivalence classes +Culled Empty Block (label) @1 +Culled Empty Block (label) @3 Culled Empty Block (label) main::@2 -Culled Empty Block (label) print_person::@4 -Culled Empty Block (label) print_ln::@2 -Culled Empty Block (label) print_ln::@3 -Culled Empty Block (label) print_dword_decimal::@2 -Culled Empty Block (label) ultoa::@1 -Culled Empty Block (label) ultoa::@8 -Culled Empty Block (label) ultoa::@28 -Renumbering block @38 to @1 -Renumbering block ultoa::@18 to ultoa::@1 -Renumbering block ultoa::@19 to ultoa::@2 -Renumbering block ultoa::@20 to ultoa::@3 -Renumbering block ultoa::@21 to ultoa::@4 -Renumbering block ultoa::@24 to ultoa::@5 -Renumbering block ultoa::@26 to ultoa::@6 -Renumbering block ultoa::@27 to ultoa::@7 -Adding NOP phi() at start of @begin +Renumbering block @2 to @1 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 print_person::@1 -Adding NOP phi() at start of print_person::@3 -Adding NOP phi() at start of print_ln -Adding NOP phi() at start of print_dword_decimal::@1 -Adding NOP phi() at start of ultoa -Adding NOP phi() at start of ultoa_append +Adding NOP phi() at start of main::@1 FINAL CONTROL FLOW GRAPH @begin: scope:[] from - [0] phi() + [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) + [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) to:@1 @1: scope:[] from @begin - [1] phi() - [2] call main + [2] phi() + [3] call main to:@end @end: scope:[] from @1 - [3] phi() + [4] phi() (void()) main() main: scope:[main] from @1 - [4] phi() - [5] call print_person + [5] phi() + [6] call print_person to:main::@1 main::@1: scope:[main] from main - [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 - [7] call print_person + [7] phi() + [8] call print_person to:main::@return main::@return: scope:[main] from main::@1 - [8] return + [9] return to:@return -(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 - [9] (byte*) print_line_cursor#20 ← phi( main/(byte*) 1024 main::@1/(byte*) print_line_cursor#1 ) - [9] (byte*) print_person::person_initials#2 ← phi( main/(const byte*) jesper_initials main::@1/(const byte*) henry_initials ) - [9] (byte*) print_char_cursor#39 ← phi( main/(byte*) 1024 main::@1/(byte*) print_char_cursor#47 ) - [9] (dword) print_person::person_id#2 ← phi( main/(const dword) jesper_id main::@1/(const dword) henry_id ) - [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 - [11] call print_dword_decimal + [10] (byte*) print_person::person_name#4 ← phi( main/(const byte*) jesper_name main::@1/(const byte*) henriette_name ) + [10] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) + [10] (byte) print_person::person_id#2 ← phi( main/(const byte) jesper_id main::@1/(const byte) henriette_id ) + [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) + [12] (byte) idx#4 ← ++ (byte) idx#13 + [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' + [14] (byte) idx#5 ← ++ (byte) idx#4 to:print_person::@1 -print_person::@1: scope:[print_person] from print_person - [12] phi() - [13] call print_char - to:print_person::@2 -print_person::@2: scope:[print_person] from print_person::@1 - [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 - [15] call print_str +print_person::@1: scope:[print_person] from print_person print_person::@2 + [15] (byte) idx#14 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 ) + [15] (byte) print_person::i#2 ← phi( print_person/(byte) 0 print_person::@2/(byte) print_person::i#1 ) + [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 to:print_person::@3 -print_person::@3: scope:[print_person] from print_person::@2 - [16] phi() - [17] call print_ln +print_person::@3: scope:[print_person] from print_person::@1 + [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' + [18] (byte) idx#16 ← ++ (byte) idx#14 to:print_person::@return print_person::@return: scope:[print_person] from print_person::@3 - [18] return + [19] return to:@return - -(void()) print_ln() -print_ln: scope:[print_ln] from print_person::@3 - [19] phi() - to:print_ln::@1 -print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 - [20] (byte*) print_line_cursor#9 ← phi( print_ln/(byte*) print_line_cursor#20 print_ln::@1/(byte*) print_line_cursor#1 ) - [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 - [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 - to:print_ln::@return -print_ln::@return: scope:[print_ln] from print_ln::@1 - [23] return - to:@return - -(void()) print_str((byte*) print_str::str) -print_str: scope:[print_str] from print_dword_decimal::@1 print_person::@2 - [24] (byte*) print_char_cursor#41 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#39 print_person::@2/(byte*) print_char_cursor#25 ) - [24] (byte*) print_str::str#5 ← phi( print_dword_decimal::@1/(const byte*) decimal_digits_long print_person::@2/(byte*) print_str::str#2 ) - to:print_str::@1 -print_str::@1: scope:[print_str] from print_str print_str::@2 - [25] (byte*) print_char_cursor#18 ← phi( print_str/(byte*) print_char_cursor#41 print_str::@2/(byte*) print_char_cursor#1 ) - [25] (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 ) - [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 - to:print_str::@return -print_str::@return: scope:[print_str] from print_str::@1 - [27] return - to:@return -print_str::@2: scope:[print_str] from print_str::@1 - [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) - [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 - [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 - to:print_str::@1 - -(void()) print_char((byte) print_char::ch) -print_char: scope:[print_char] from print_person::@1 - [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 - [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 - to:print_char::@return -print_char::@return: scope:[print_char] from print_char - [33] return - to:@return - -(void()) print_dword_decimal((dword) print_dword_decimal::w) -print_dword_decimal: scope:[print_dword_decimal] from print_person - [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 - [35] call ultoa - to:print_dword_decimal::@1 -print_dword_decimal::@1: scope:[print_dword_decimal] from print_dword_decimal - [36] phi() - [37] call print_str - to:print_dword_decimal::@return -print_dword_decimal::@return: scope:[print_dword_decimal] from print_dword_decimal::@1 - [38] return - to:@return - -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -ultoa: scope:[ultoa] from print_dword_decimal - [39] phi() - to:ultoa::@1 -ultoa::@1: scope:[ultoa] from ultoa ultoa::@4 - [40] (byte*) ultoa::buffer#11 ← phi( ultoa::@4/(byte*) ultoa::buffer#14 ultoa/(const byte*) decimal_digits_long ) - [40] (byte) ultoa::started#2 ← phi( ultoa::@4/(byte) ultoa::started#4 ultoa/(byte) 0 ) - [40] (dword) ultoa::value#2 ← phi( ultoa::@4/(dword) ultoa::value#6 ultoa/(dword) ultoa::value#1 ) - [40] (byte) ultoa::digit#2 ← phi( ultoa::@4/(byte) ultoa::digit#1 ultoa/(byte) 0 ) - [41] if((byte) ultoa::digit#2<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 - to:ultoa::@3 -ultoa::@3: scope:[ultoa] from ultoa::@1 - [42] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#2 - [43] *((byte*) ultoa::buffer#11) ← *((const byte*) DIGITS + (byte~) ultoa::$4) - [44] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 - [45] *((byte*) ultoa::buffer#3) ← (byte) 0 - to:ultoa::@return -ultoa::@return: scope:[ultoa] from ultoa::@3 - [46] return - to:@return -ultoa::@2: scope:[ultoa] from ultoa::@1 - [47] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 << (byte) 2 - [48] (dword) ultoa::digit_value#0 ← *((const dword*) RADIX_DECIMAL_VALUES_LONG + (byte~) ultoa::$11) - [49] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 - to:ultoa::@7 -ultoa::@7: scope:[ultoa] from ultoa::@2 - [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 - to:ultoa::@4 -ultoa::@4: scope:[ultoa] from ultoa::@6 ultoa::@7 - [51] (byte*) ultoa::buffer#14 ← phi( ultoa::@7/(byte*) ultoa::buffer#11 ultoa::@6/(byte*) ultoa::buffer#4 ) - [51] (byte) ultoa::started#4 ← phi( ultoa::@7/(byte) ultoa::started#2 ultoa::@6/(byte) 1 ) - [51] (dword) ultoa::value#6 ← phi( ultoa::@7/(dword) ultoa::value#2 ultoa::@6/(dword) ultoa::value#0 ) - [52] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#2 - to:ultoa::@1 -ultoa::@5: scope:[ultoa] from ultoa::@2 ultoa::@7 - [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 - [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 - [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 - [56] call ultoa_append - [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 - to:ultoa::@6 -ultoa::@6: scope:[ultoa] from ultoa::@5 - [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 - [59] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#11 - to:ultoa::@4 - -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -ultoa_append: scope:[ultoa_append] from ultoa::@5 - [60] phi() - to:ultoa_append::@1 -ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2 - [61] (byte) ultoa_append::digit#2 ← phi( ultoa_append/(byte) 0 ultoa_append::@2/(byte) ultoa_append::digit#1 ) - [61] (dword) ultoa_append::value#2 ← phi( ultoa_append/(dword) ultoa_append::value#0 ultoa_append::@2/(dword) ultoa_append::value#1 ) - [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 - to:ultoa_append::@3 -ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1 - [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) - to:ultoa_append::@return -ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3 - [64] return - to:@return -ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1 - [65] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 - [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 - to:ultoa_append::@1 +print_person::@2: scope:[print_person] from print_person::@1 + [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) + [21] (byte) idx#6 ← ++ (byte) idx#14 + [22] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 + to:print_person::@1 VARIABLE REGISTER WEIGHTS -(dword) Person::id +(byte) Person::id +(byte) idx +(byte) idx#13 3.0 +(byte) idx#14 9.75 +(byte) idx#16 1.0 +(byte) idx#4 3.0 +(byte) idx#5 4.0 +(byte) idx#6 11.0 (void()) main() -(void()) print_char((byte) print_char::ch) -(byte) print_char::ch -(byte*) print_char_cursor -(byte*) print_char_cursor#1 11.0 -(byte*) print_char_cursor#18 3.333333333333333 -(byte*) print_char_cursor#25 1.0 -(byte*) print_char_cursor#39 0.8 -(byte*) print_char_cursor#41 6.0 -(byte*) print_char_cursor#47 4.0 -(void()) print_dword_decimal((dword) print_dword_decimal::w) -(dword) print_dword_decimal::w -(dword) print_dword_decimal::w#0 4.0 -(byte*) print_line_cursor -(byte*) print_line_cursor#1 5.285714285714286 -(byte*) print_line_cursor#20 0.4444444444444444 -(byte*) print_line_cursor#9 24.0 -(void()) print_ln() -(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) +(byte) print_person::i +(byte) print_person::i#1 22.0 +(byte) print_person::i#2 11.0 (struct Person) print_person::person -(dword) print_person::person_id -(dword) print_person::person_id#2 2.0 -(const byte*) print_person::person_initials -(byte*) print_person::person_initials#2 0.4 -(byte*) print_screen -(void()) print_str((byte*) print_str::str) -(byte*) print_str::str -(byte*) print_str::str#0 22.0 -(byte*) print_str::str#2 4.0 -(byte*) print_str::str#3 11.5 -(byte*) print_str::str#5 4.0 -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -(byte~) ultoa::$11 22.0 -(byte~) ultoa::$4 4.0 -(byte*) ultoa::buffer -(byte*) ultoa::buffer#11 3.4285714285714284 -(byte*) ultoa::buffer#14 16.5 -(byte*) ultoa::buffer#3 4.0 -(byte*) ultoa::buffer#4 22.0 -(byte) ultoa::digit -(byte) ultoa::digit#1 22.0 -(byte) ultoa::digit#2 3.142857142857143 -(dword) ultoa::digit_value -(dword) ultoa::digit_value#0 6.6000000000000005 -(dword*) ultoa::digit_values -(byte) ultoa::max_digits -(byte) ultoa::radix -(byte) ultoa::started -(byte) ultoa::started#2 5.5 -(byte) ultoa::started#4 11.0 -(dword) ultoa::value -(dword) ultoa::value#0 11.0 -(dword) ultoa::value#1 2.0 -(dword) ultoa::value#2 6.571428571428571 -(dword) ultoa::value#6 16.5 -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -(byte*) ultoa_append::buffer -(byte*) ultoa_append::buffer#0 1.625 -(byte) ultoa_append::digit -(byte) ultoa_append::digit#1 101.0 -(byte) ultoa_append::digit#2 102.0 -(dword) ultoa_append::return -(dword) ultoa_append::return#0 22.0 -(dword) ultoa_append::sub -(dword) ultoa_append::sub#0 35.5 -(dword) ultoa_append::value -(dword) ultoa_append::value#0 4.333333333333333 -(dword) ultoa_append::value#1 202.0 -(dword) ultoa_append::value#2 52.66666666666666 +(byte) print_person::person_id +(byte) print_person::person_id#2 2.0 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 2.2 Initial phi equivalence classes [ print_person::person_id#2 ] -[ print_person::person_initials#2 ] -[ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] -[ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -[ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -[ ultoa::digit#2 ultoa::digit#1 ] -[ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] -[ ultoa::started#2 ultoa::started#4 ] -[ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] -[ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] -[ ultoa_append::digit#2 ultoa_append::digit#1 ] -Added variable print_dword_decimal::w#0 to live range equivalence class [ print_dword_decimal::w#0 ] -Added variable ultoa::$4 to live range equivalence class [ ultoa::$4 ] -Added variable ultoa::buffer#3 to live range equivalence class [ ultoa::buffer#3 ] -Added variable ultoa::$11 to live range equivalence class [ ultoa::$11 ] -Added variable ultoa::digit_value#0 to live range equivalence class [ ultoa::digit_value#0 ] -Added variable ultoa_append::buffer#0 to live range equivalence class [ ultoa_append::buffer#0 ] -Added variable ultoa_append::sub#0 to live range equivalence class [ ultoa_append::sub#0 ] -Added variable ultoa_append::return#0 to live range equivalence class [ ultoa_append::return#0 ] +[ idx#13 idx#16 ] +[ print_person::person_name#4 ] +[ print_person::i#2 print_person::i#1 ] +[ idx#14 idx#5 idx#6 ] +Added variable idx#4 to live range equivalence class [ idx#4 ] Complete equivalence classes [ print_person::person_id#2 ] -[ print_person::person_initials#2 ] -[ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] -[ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -[ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -[ ultoa::digit#2 ultoa::digit#1 ] -[ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] -[ ultoa::started#2 ultoa::started#4 ] -[ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] -[ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] -[ ultoa_append::digit#2 ultoa_append::digit#1 ] -[ print_dword_decimal::w#0 ] -[ ultoa::$4 ] -[ ultoa::buffer#3 ] -[ ultoa::$11 ] -[ ultoa::digit_value#0 ] -[ ultoa_append::buffer#0 ] -[ ultoa_append::sub#0 ] -[ ultoa_append::return#0 ] -Allocated zp[4]:2 [ print_person::person_id#2 ] -Allocated zp[2]:6 [ print_person::person_initials#2 ] -Allocated zp[2]:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] -Allocated zp[2]:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -Allocated zp[2]:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -Allocated zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] -Allocated zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] -Allocated zp[1]:19 [ ultoa::started#2 ultoa::started#4 ] -Allocated zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] -Allocated zp[4]:22 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] -Allocated zp[1]:26 [ ultoa_append::digit#2 ultoa_append::digit#1 ] -Allocated zp[4]:27 [ print_dword_decimal::w#0 ] -Allocated zp[1]:31 [ ultoa::$4 ] -Allocated zp[2]:32 [ ultoa::buffer#3 ] -Allocated zp[1]:34 [ ultoa::$11 ] -Allocated zp[4]:35 [ ultoa::digit_value#0 ] -Allocated zp[2]:39 [ ultoa_append::buffer#0 ] -Allocated zp[4]:41 [ ultoa_append::sub#0 ] -Allocated zp[4]:45 [ ultoa_append::return#0 ] +[ idx#13 idx#16 ] +[ print_person::person_name#4 ] +[ print_person::i#2 print_person::i#1 ] +[ idx#14 idx#5 idx#6 ] +[ idx#4 ] +Allocated zp[1]:2 [ print_person::person_id#2 ] +Allocated zp[1]:3 [ idx#13 idx#16 ] +Allocated zp[2]:4 [ print_person::person_name#4 ] +Allocated zp[1]:6 [ print_person::i#2 print_person::i#1 ] +Allocated zp[1]:7 [ idx#14 idx#5 idx#6 ] +Allocated zp[1]:8 [ idx#4 ] INITIAL ASM Target platform is c64basic / MOS6502X // File Comments // Example of a struct containing an array +// Works because the struct is only handled as a value // Upstart .pc = $801 "Basic" :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels - .const jesper_id = $1b244 - .const henry_id = $4466d - .label print_char_cursor = $c - .label print_line_cursor = 8 + .label SCREEN = $400 + .const jesper_id = 4 + .const henriette_id = 7 + .label idx = 8 + .label idx_1 = 7 + .label idx_2 = 3 // @begin __bbegin: - // [1] phi from @begin to @1 [phi:@begin->@1] + // [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 +!: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- + // [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 +!: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- + // [2] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 // @1 __b1: - // [2] call main - // [4] phi from @1 to main [phi:@1->main] + // [3] call main + // [5] phi from @1 to main [phi:@1->main] main_from___b1: jsr main - // [3] phi from @1 to @end [phi:@1->@end] + // [4] phi from @1 to @end [phi:@1->@end] __bend_from___b1: jmp __bend // @end __bend: // main main: { - // [5] call print_person - // [9] phi from main to print_person [phi:main->print_person] + // [6] call print_person + // [10] phi from main to print_person [phi:main->print_person] print_person_from_main: - // [9] phi (byte*) print_line_cursor#20 = (byte*) 1024 [phi:main->print_person#0] -- pbuz1=pbuc1 - lda #<$400 - sta.z print_line_cursor - lda #>$400 - sta.z print_line_cursor+1 - // [9] phi (byte*) print_person::person_initials#2 = (const byte*) jesper_initials [phi:main->print_person#1] -- pbuz1=pbuc1 - lda #jesper_initials - sta.z print_person.person_initials+1 - // [9] phi (byte*) print_char_cursor#39 = (byte*) 1024 [phi:main->print_person#2] -- pbuz1=pbuc1 - lda #<$400 - sta.z print_char_cursor - lda #>$400 - sta.z print_char_cursor+1 - // [9] phi (dword) print_person::person_id#2 = (const dword) jesper_id [phi:main->print_person#3] -- vduz1=vduc1 - lda #print_person#0] -- pbuz1=pbuc1 + lda #jesper_name + sta.z print_person.person_name+1 + // [10] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1 + lda #0 + sta.z idx_2 + // [10] phi (byte) print_person::person_id#2 = (const byte) jesper_id [phi:main->print_person#2] -- vbuz1=vbuc1 + lda #jesper_id sta.z print_person.person_id - lda #>jesper_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>jesper_id>>$10 - sta.z print_person.person_id+3 jsr print_person + // [7] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: jmp __b1 // main::@1 __b1: - // [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 - lda.z print_line_cursor - sta.z print_char_cursor - lda.z print_line_cursor+1 - sta.z print_char_cursor+1 - // [7] call print_person - // [9] phi from main::@1 to print_person [phi:main::@1->print_person] + // [8] call print_person + // [10] phi from main::@1 to print_person [phi:main::@1->print_person] print_person_from___b1: - // [9] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#1 [phi:main::@1->print_person#0] -- register_copy - // [9] phi (byte*) print_person::person_initials#2 = (const byte*) henry_initials [phi:main::@1->print_person#1] -- pbuz1=pbuc1 - lda #henry_initials - sta.z print_person.person_initials+1 - // [9] phi (byte*) print_char_cursor#39 = (byte*) print_char_cursor#47 [phi:main::@1->print_person#2] -- register_copy - // [9] phi (dword) print_person::person_id#2 = (const dword) henry_id [phi:main::@1->print_person#3] -- vduz1=vduc1 - lda #print_person#0] -- pbuz1=pbuc1 + lda #henriette_name + sta.z print_person.person_name+1 + // [10] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy + // [10] phi (byte) print_person::person_id#2 = (const byte) henriette_id [phi:main::@1->print_person#2] -- vbuz1=vbuc1 + lda #henriette_id sta.z print_person.person_id - lda #>henry_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>henry_id>>$10 - sta.z print_person.person_id+3 jsr print_person jmp __breturn // main::@return __breturn: - // [8] return + // [9] return rts } // print_person -// print_person(dword zeropage(2) person_id, byte* zeropage(6) person_initials) +// print_person(byte zp(2) person_id, byte* zp(4) person_name) print_person: { + .label i = 6 .label person_id = 2 - .label person_initials = 6 - // [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 -- vduz1=vduz2 - lda.z person_id - sta.z print_dword_decimal.w - lda.z person_id+1 - sta.z print_dword_decimal.w+1 - lda.z person_id+2 - sta.z print_dword_decimal.w+2 - lda.z person_id+3 - sta.z print_dword_decimal.w+3 - // [11] call print_dword_decimal - jsr print_dword_decimal - // [12] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] + .label person_name = 4 + // [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2 + ldy.z person_id + lda DIGIT,y + ldy.z idx_2 + sta SCREEN,y + // [12] (byte) idx#4 ← ++ (byte) idx#13 -- vbuz1=_inc_vbuz2 + ldy.z idx_2 + iny + sty.z idx + // [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #' ' + ldy.z idx + sta SCREEN,y + // [14] (byte) idx#5 ← ++ (byte) idx#4 -- vbuz1=_inc_vbuz2 + ldy.z idx + iny + sty.z idx_1 + // [15] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] __b1_from_print_person: + // [15] phi (byte) idx#14 = (byte) idx#5 [phi:print_person->print_person::@1#0] -- register_copy + // [15] phi (byte) print_person::i#2 = (byte) 0 [phi:print_person->print_person::@1#1] -- vbuz1=vbuc1 + lda #0 + sta.z i jmp __b1 // print_person::@1 __b1: - // [13] call print_char - jsr print_char - jmp __b2 - // print_person::@2 - __b2: - // [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 -- pbuz1=pbuz2 - lda.z person_initials - sta.z print_str.str - lda.z person_initials+1 - sta.z print_str.str+1 - // [15] call print_str - // [24] phi from print_person::@2 to print_str [phi:print_person::@2->print_str] - print_str_from___b2: - // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#25 [phi:print_person::@2->print_str#0] -- register_copy - // [24] phi (byte*) print_str::str#5 = (byte*) print_str::str#2 [phi:print_person::@2->print_str#1] -- register_copy - jsr print_str - // [16] phi from print_person::@2 to print_person::@3 [phi:print_person::@2->print_person::@3] - __b3_from___b2: + // [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 -- vbuc1_neq_pbuz1_derefidx_vbuz2_then_la1 + ldy.z i + lda (person_name),y + cmp #0 + bne __b2 jmp __b3 // print_person::@3 __b3: - // [17] call print_ln - // [19] phi from print_person::@3 to print_ln [phi:print_person::@3->print_ln] - print_ln_from___b3: - jsr print_ln + // [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #' ' + ldy.z idx_1 + sta SCREEN,y + // [18] (byte) idx#16 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz2 + ldy.z idx_1 + iny + sty.z idx_2 jmp __breturn // print_person::@return __breturn: - // [18] return + // [19] return rts -} - // print_ln -// Print a newline -print_ln: { - // [20] 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: - // [20] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#20 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy - jmp __b1 - // print_ln::@1 - __b1: - // [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 -- pbuz1=pbuz1_plus_vbuc1 - lda #$28 - clc - adc.z print_line_cursor - sta.z print_line_cursor - bcc !+ - inc.z print_line_cursor+1 - !: - // [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 - lda.z print_line_cursor+1 - cmp.z print_char_cursor+1 - bcc __b1_from___b1 - bne !+ - lda.z print_line_cursor - cmp.z print_char_cursor - bcc __b1_from___b1 - !: - jmp __breturn - // print_ln::@return - __breturn: - // [23] return - rts -} - // print_str -// Print a zero-terminated string -// print_str(byte* zeropage($a) str) -print_str: { - .label str = $a - // [25] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] - __b1_from_print_str: + // print_person::@2 + __b2: + // [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) -- pbuc1_derefidx_vbuz1=pbuz2_derefidx_vbuz3 + ldx.z idx_1 + ldy.z i + lda (person_name),y + sta SCREEN,x + // [21] (byte) idx#6 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz1 + inc.z idx_1 + // [22] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // [15] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1] __b1_from___b2: - // [25] phi (byte*) print_char_cursor#18 = (byte*) print_char_cursor#41 [phi:print_str/print_str::@2->print_str::@1#0] -- register_copy - // [25] phi (byte*) print_str::str#3 = (byte*) print_str::str#5 [phi:print_str/print_str::@2->print_str::@1#1] -- register_copy - jmp __b1 - // print_str::@1 - __b1: - // [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 - ldy #0 - lda (str),y - cmp #0 - bne __b2 - jmp __breturn - // print_str::@return - __breturn: - // [27] return - rts - // print_str::@2 - __b2: - // [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) -- _deref_pbuz1=_deref_pbuz2 - ldy #0 - lda (str),y - ldy #0 - sta (print_char_cursor),y - // [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - // [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 -- pbuz1=_inc_pbuz1 - inc.z str - bne !+ - inc.z str+1 - !: - jmp __b1_from___b2 -} - // print_char -// Print a single char -print_char: { - .const ch = ' ' - // [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 -- _deref_pbuz1=vbuc1 - lda #ch - ldy #0 - sta (print_char_cursor),y - // [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - jmp __breturn - // print_char::@return - __breturn: - // [33] return - rts -} - // print_dword_decimal -// Print a dword as DECIMAL -// print_dword_decimal(dword zeropage($1b) w) -print_dword_decimal: { - .label w = $1b - // [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 -- vduz1=vduz2 - lda.z w - sta.z ultoa.value - lda.z w+1 - sta.z ultoa.value+1 - lda.z w+2 - sta.z ultoa.value+2 - lda.z w+3 - sta.z ultoa.value+3 - // [35] call ultoa - // [39] phi from print_dword_decimal to ultoa [phi:print_dword_decimal->ultoa] - ultoa_from_print_dword_decimal: - jsr ultoa - // [36] phi from print_dword_decimal to print_dword_decimal::@1 [phi:print_dword_decimal->print_dword_decimal::@1] - __b1_from_print_dword_decimal: - jmp __b1 - // print_dword_decimal::@1 - __b1: - // [37] call print_str - // [24] phi from print_dword_decimal::@1 to print_str [phi:print_dword_decimal::@1->print_str] - print_str_from___b1: - // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#39 [phi:print_dword_decimal::@1->print_str#0] -- register_copy - // [24] phi (byte*) print_str::str#5 = (const byte*) decimal_digits_long [phi:print_dword_decimal::@1->print_str#1] -- pbuz1=pbuc1 - lda #decimal_digits_long - sta.z print_str.str+1 - jsr print_str - jmp __breturn - // print_dword_decimal::@return - __breturn: - // [38] return - rts -} - // ultoa -// Converts unsigned number value to a string representing it in RADIX format. -// If the leading digits are zero they are not included in the string. -// - value : The number to be converted to RADIX -// - buffer : receives the string representing the number and zero-termination. -// - radix : The radix to convert the number to (from the enum RADIX) -// ultoa(dword zeropage($f) value, byte* zeropage($20) buffer) -ultoa: { - .const max_digits = $a - .label __4 = $1f - .label __11 = $22 - .label digit_value = $23 - .label buffer = $20 - .label digit = $e - .label value = $f - .label buffer_1 = $14 - .label started = $13 - // [40] phi from ultoa to ultoa::@1 [phi:ultoa->ultoa::@1] - __b1_from_ultoa: - // [40] phi (byte*) ultoa::buffer#11 = (const byte*) decimal_digits_long [phi:ultoa->ultoa::@1#0] -- pbuz1=pbuc1 - lda #decimal_digits_long - sta.z buffer_1+1 - // [40] phi (byte) ultoa::started#2 = (byte) 0 [phi:ultoa->ultoa::@1#1] -- vbuz1=vbuc1 - lda #0 - sta.z started - // [40] phi (dword) ultoa::value#2 = (dword) ultoa::value#1 [phi:ultoa->ultoa::@1#2] -- register_copy - // [40] phi (byte) ultoa::digit#2 = (byte) 0 [phi:ultoa->ultoa::@1#3] -- vbuz1=vbuc1 - lda #0 - sta.z digit - jmp __b1 - // ultoa::@1 - __b1: - // [41] if((byte) ultoa::digit#2<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 -- vbuz1_lt_vbuc1_then_la1 - lda.z digit - cmp #max_digits-1 - bcc __b2 - jmp __b3 - // ultoa::@3 - __b3: - // [42] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#2 -- vbuz1=_byte_vduz2 - lda.z value - sta.z __4 - // [43] *((byte*) ultoa::buffer#11) ← *((const byte*) DIGITS + (byte~) ultoa::$4) -- _deref_pbuz1=pbuc1_derefidx_vbuz2 - ldy.z __4 - lda DIGITS,y - ldy #0 - sta (buffer_1),y - // [44] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz2 - lda.z buffer_1 - clc - adc #1 - sta.z buffer - lda.z buffer_1+1 - adc #0 - sta.z buffer+1 - // [45] *((byte*) ultoa::buffer#3) ← (byte) 0 -- _deref_pbuz1=vbuc1 - lda #0 - ldy #0 - sta (buffer),y - jmp __breturn - // ultoa::@return - __breturn: - // [46] return - rts - // ultoa::@2 - __b2: - // [47] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 << (byte) 2 -- vbuz1=vbuz2_rol_2 - lda.z digit - asl - asl - sta.z __11 - // [48] (dword) ultoa::digit_value#0 ← *((const dword*) RADIX_DECIMAL_VALUES_LONG + (byte~) ultoa::$11) -- vduz1=pduc1_derefidx_vbuz2 - ldy.z __11 - lda RADIX_DECIMAL_VALUES_LONG,y - sta.z digit_value - lda RADIX_DECIMAL_VALUES_LONG+1,y - sta.z digit_value+1 - lda RADIX_DECIMAL_VALUES_LONG+2,y - sta.z digit_value+2 - lda RADIX_DECIMAL_VALUES_LONG+3,y - sta.z digit_value+3 - // [49] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 -- vbuc1_neq_vbuz1_then_la1 - lda #0 - cmp.z started - bne __b5 - jmp __b7 - // ultoa::@7 - __b7: - // [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 -- vduz1_ge_vduz2_then_la1 - lda.z value+3 - cmp.z digit_value+3 - bcc !+ - bne __b5 - lda.z value+2 - cmp.z digit_value+2 - bcc !+ - bne __b5 - lda.z value+1 - cmp.z digit_value+1 - bcc !+ - bne __b5 - lda.z value - cmp.z digit_value - bcs __b5 - !: - // [51] phi from ultoa::@7 to ultoa::@4 [phi:ultoa::@7->ultoa::@4] - __b4_from___b7: - // [51] phi (byte*) ultoa::buffer#14 = (byte*) ultoa::buffer#11 [phi:ultoa::@7->ultoa::@4#0] -- register_copy - // [51] phi (byte) ultoa::started#4 = (byte) ultoa::started#2 [phi:ultoa::@7->ultoa::@4#1] -- register_copy - // [51] phi (dword) ultoa::value#6 = (dword) ultoa::value#2 [phi:ultoa::@7->ultoa::@4#2] -- register_copy - jmp __b4 - // ultoa::@4 - __b4: - // [52] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#2 -- vbuz1=_inc_vbuz1 - inc.z digit - // [40] phi from ultoa::@4 to ultoa::@1 [phi:ultoa::@4->ultoa::@1] - __b1_from___b4: - // [40] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#14 [phi:ultoa::@4->ultoa::@1#0] -- register_copy - // [40] phi (byte) ultoa::started#2 = (byte) ultoa::started#4 [phi:ultoa::@4->ultoa::@1#1] -- register_copy - // [40] phi (dword) ultoa::value#2 = (dword) ultoa::value#6 [phi:ultoa::@4->ultoa::@1#2] -- register_copy - // [40] phi (byte) ultoa::digit#2 = (byte) ultoa::digit#1 [phi:ultoa::@4->ultoa::@1#3] -- register_copy - jmp __b1 - // ultoa::@5 - __b5: - // [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 -- pbuz1=pbuz2 - lda.z buffer_1 - sta.z ultoa_append.buffer - lda.z buffer_1+1 - sta.z ultoa_append.buffer+1 - // [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 -- vduz1=vduz2 - lda.z value - sta.z ultoa_append.value - lda.z value+1 - sta.z ultoa_append.value+1 - lda.z value+2 - sta.z ultoa_append.value+2 - lda.z value+3 - sta.z ultoa_append.value+3 - // [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 -- vduz1=vduz2 - lda.z digit_value - sta.z ultoa_append.sub - lda.z digit_value+1 - sta.z ultoa_append.sub+1 - lda.z digit_value+2 - sta.z ultoa_append.sub+2 - lda.z digit_value+3 - sta.z ultoa_append.sub+3 - // [56] call ultoa_append - // [60] phi from ultoa::@5 to ultoa_append [phi:ultoa::@5->ultoa_append] - ultoa_append_from___b5: - jsr ultoa_append - // [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 -- vduz1=vduz2 - lda.z ultoa_append.value - sta.z ultoa_append.return - lda.z ultoa_append.value+1 - sta.z ultoa_append.return+1 - lda.z ultoa_append.value+2 - sta.z ultoa_append.return+2 - lda.z ultoa_append.value+3 - sta.z ultoa_append.return+3 - jmp __b6 - // ultoa::@6 - __b6: - // [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 -- vduz1=vduz2 - lda.z ultoa_append.return - sta.z value - lda.z ultoa_append.return+1 - sta.z value+1 - lda.z ultoa_append.return+2 - sta.z value+2 - lda.z ultoa_append.return+3 - sta.z value+3 - // [59] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz1 - inc.z buffer_1 - bne !+ - inc.z buffer_1+1 - !: - // [51] phi from ultoa::@6 to ultoa::@4 [phi:ultoa::@6->ultoa::@4] - __b4_from___b6: - // [51] phi (byte*) ultoa::buffer#14 = (byte*) ultoa::buffer#4 [phi:ultoa::@6->ultoa::@4#0] -- register_copy - // [51] phi (byte) ultoa::started#4 = (byte) 1 [phi:ultoa::@6->ultoa::@4#1] -- vbuz1=vbuc1 - lda #1 - sta.z started - // [51] phi (dword) ultoa::value#6 = (dword) ultoa::value#0 [phi:ultoa::@6->ultoa::@4#2] -- register_copy - jmp __b4 -} - // ultoa_append -// Used to convert a single digit of an unsigned number value to a string representation -// Counts a single digit up from '0' as long as the value is larger than sub. -// Each time the digit is increased sub is subtracted from value. -// - buffer : pointer to the char that receives the digit -// - value : The value where the digit will be derived from -// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. -// (For decimal the subs used are 10000, 1000, 100, 10, 1) -// returns : the value reduced by sub * digit so that it is less than sub. -// ultoa_append(byte* zeropage($27) buffer, dword zeropage($16) value, dword zeropage($29) sub) -ultoa_append: { - .label buffer = $27 - .label value = $16 - .label sub = $29 - .label return = $2d - .label digit = $1a - // [61] phi from ultoa_append to ultoa_append::@1 [phi:ultoa_append->ultoa_append::@1] - __b1_from_ultoa_append: - // [61] phi (byte) ultoa_append::digit#2 = (byte) 0 [phi:ultoa_append->ultoa_append::@1#0] -- vbuz1=vbuc1 - lda #0 - sta.z digit - // [61] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#0 [phi:ultoa_append->ultoa_append::@1#1] -- register_copy - jmp __b1 - // ultoa_append::@1 - __b1: - // [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -- vduz1_ge_vduz2_then_la1 - lda.z value+3 - cmp.z sub+3 - bcc !+ - bne __b2 - lda.z value+2 - cmp.z sub+2 - bcc !+ - bne __b2 - lda.z value+1 - cmp.z sub+1 - bcc !+ - bne __b2 - lda.z value - cmp.z sub - bcs __b2 - !: - jmp __b3 - // ultoa_append::@3 - __b3: - // [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) -- _deref_pbuz1=pbuc1_derefidx_vbuz2 - ldy.z digit - lda DIGITS,y - ldy #0 - sta (buffer),y - jmp __breturn - // ultoa_append::@return - __breturn: - // [64] return - rts - // ultoa_append::@2 - __b2: - // [65] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 -- vbuz1=_inc_vbuz1 - inc.z digit - // [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 -- vduz1=vduz1_minus_vduz2 - lda.z value - sec - sbc.z sub - sta.z value - lda.z value+1 - sbc.z sub+1 - sta.z value+1 - lda.z value+2 - sbc.z sub+2 - sta.z value+2 - lda.z value+3 - sbc.z sub+3 - sta.z value+3 - // [61] phi from ultoa_append::@2 to ultoa_append::@1 [phi:ultoa_append::@2->ultoa_append::@1] - __b1_from___b2: - // [61] phi (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#1 [phi:ultoa_append::@2->ultoa_append::@1#0] -- register_copy - // [61] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#1 [phi:ultoa_append::@2->ultoa_append::@1#1] -- register_copy + // [15] phi (byte) idx#14 = (byte) idx#6 [phi:print_person::@2->print_person::@1#0] -- register_copy + // [15] phi (byte) print_person::i#2 = (byte) print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy jmp __b1 } // File Data - // The digits used for numbers - DIGITS: .text "0123456789abcdef" - // Values of decimal digits - RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a - // Digits used for storing the decimal word - decimal_digits_long: .fill $b, 0 - jesper_initials: .text "jg" + DIGIT: .text "0123456789" .byte 0 - henry_initials: .text "hg" + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 + __0: .text "jesper" .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 REGISTER UPLIFT POTENTIAL REGISTERS -Statement [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 [ print_char_cursor#47 print_line_cursor#1 ] ( main:2 [ print_char_cursor#47 print_line_cursor#1 ] ) always clobbers reg byte a -Statement [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ( main:2::print_person:5 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] main:2::print_person:7 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ) always clobbers reg byte a -Statement [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ( main:2::print_person:5 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] main:2::print_person:7 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ) always clobbers reg byte a -Statement [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a -Statement [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a -Statement [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y -Statement [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y -Statement [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 [ print_char_cursor#18 ] ( main:2::print_person:5::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] main:2::print_person:7::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] ) always clobbers reg byte a reg byte y -Statement [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 [ print_char_cursor#39 ultoa::value#1 ] ( main:2::print_person:5::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] main:2::print_person:7::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] ) always clobbers reg byte a -Statement [42] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#2 [ ultoa::buffer#11 ultoa::$4 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] ) always clobbers reg byte a -Statement [43] *((byte*) ultoa::buffer#11) ← *((const byte*) DIGITS + (byte~) ultoa::$4) [ ultoa::buffer#11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] ) always clobbers reg byte a reg byte y -Statement [44] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 [ ultoa::buffer#3 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] ) always clobbers reg byte a -Statement [45] *((byte*) ultoa::buffer#3) ← (byte) 0 [ ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] ) always clobbers reg byte a reg byte y -Statement [47] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 << (byte) 2 [ ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] -Removing always clobbered register reg byte a as potential for zp[1]:19 [ ultoa::started#2 ultoa::started#4 ] -Statement [48] (dword) ultoa::digit_value#0 ← *((const dword*) RADIX_DECIMAL_VALUES_LONG + (byte~) ultoa::$11) [ ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ) always clobbers reg byte a -Statement [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 [ ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ) always clobbers reg byte a -Statement [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 [ ultoa::digit#2 ultoa::value#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ] ) always clobbers reg byte a -Statement [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 [ ultoa::digit#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ultoa_append::value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ultoa_append::value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ultoa_append::value#0 ] ) always clobbers reg byte a -Statement [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 [ ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ) always clobbers reg byte a -Statement [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 [ ultoa::digit#2 ultoa::buffer#11 ultoa_append::return#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::return#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::return#0 ] ) always clobbers reg byte a -Statement [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 [ ultoa::digit#2 ultoa::buffer#11 ultoa::value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::value#0 ] ) always clobbers reg byte a -Statement [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:26 [ ultoa_append::digit#2 ultoa_append::digit#1 ] -Statement [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) [ ultoa_append::value#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::value#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::value#2 ] ) always clobbers reg byte a reg byte y -Removing always clobbered register reg byte y as potential for zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] -Statement [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ) always clobbers reg byte a -Statement [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 [ print_char_cursor#47 print_line_cursor#1 ] ( main:2 [ print_char_cursor#47 print_line_cursor#1 ] ) always clobbers reg byte a -Statement [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ( main:2::print_person:5 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] main:2::print_person:7 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ) always clobbers reg byte a -Statement [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ( main:2::print_person:5 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] main:2::print_person:7 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ) always clobbers reg byte a -Statement [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a -Statement [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a -Statement [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y -Statement [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y -Statement [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 [ print_char_cursor#18 ] ( main:2::print_person:5::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] main:2::print_person:7::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] ) always clobbers reg byte a reg byte y -Statement [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 [ print_char_cursor#39 ultoa::value#1 ] ( main:2::print_person:5::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] main:2::print_person:7::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] ) always clobbers reg byte a -Statement [42] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#2 [ ultoa::buffer#11 ultoa::$4 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] ) always clobbers reg byte a -Statement [43] *((byte*) ultoa::buffer#11) ← *((const byte*) DIGITS + (byte~) ultoa::$4) [ ultoa::buffer#11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] ) always clobbers reg byte a reg byte y -Statement [44] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 [ ultoa::buffer#3 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] ) always clobbers reg byte a -Statement [45] *((byte*) ultoa::buffer#3) ← (byte) 0 [ ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] ) always clobbers reg byte a reg byte y -Statement [47] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 << (byte) 2 [ ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ) always clobbers reg byte a -Statement [48] (dword) ultoa::digit_value#0 ← *((const dword*) RADIX_DECIMAL_VALUES_LONG + (byte~) ultoa::$11) [ ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ) always clobbers reg byte a -Statement [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 [ ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ) always clobbers reg byte a -Statement [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 [ ultoa::digit#2 ultoa::value#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::value#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ] ) always clobbers reg byte a -Statement [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 [ ultoa::digit#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ultoa_append::value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ultoa_append::value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::digit_value#0 ultoa_append::buffer#0 ultoa_append::value#0 ] ) always clobbers reg byte a -Statement [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 [ ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ) always clobbers reg byte a -Statement [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 [ ultoa::digit#2 ultoa::buffer#11 ultoa_append::return#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::return#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::return#0 ] ) always clobbers reg byte a -Statement [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 [ ultoa::digit#2 ultoa::buffer#11 ultoa::value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa::value#0 ] ) always clobbers reg byte a -Statement [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ) always clobbers reg byte a -Statement [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) [ ultoa_append::value#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::value#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::value#2 ] ) always clobbers reg byte a reg byte y -Statement [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:56 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#2 ultoa::buffer#11 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ) always clobbers reg byte a -Potential registers zp[4]:2 [ print_person::person_id#2 ] : zp[4]:2 , -Potential registers zp[2]:6 [ print_person::person_initials#2 ] : zp[2]:6 , -Potential registers zp[2]:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] : zp[2]:8 , -Potential registers zp[2]:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] : zp[2]:10 , -Potential registers zp[2]:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] : zp[2]:12 , -Potential registers zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] : zp[1]:14 , reg byte x , -Potential registers zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] : zp[4]:15 , -Potential registers zp[1]:19 [ ultoa::started#2 ultoa::started#4 ] : zp[1]:19 , reg byte x , reg byte y , -Potential registers zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] : zp[2]:20 , -Potential registers zp[4]:22 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] : zp[4]:22 , -Potential registers zp[1]:26 [ ultoa_append::digit#2 ultoa_append::digit#1 ] : zp[1]:26 , reg byte x , reg byte y , -Potential registers zp[4]:27 [ print_dword_decimal::w#0 ] : zp[4]:27 , -Potential registers zp[1]:31 [ ultoa::$4 ] : zp[1]:31 , reg byte a , reg byte x , reg byte y , -Potential registers zp[2]:32 [ ultoa::buffer#3 ] : zp[2]:32 , -Potential registers zp[1]:34 [ ultoa::$11 ] : zp[1]:34 , reg byte a , reg byte x , reg byte y , -Potential registers zp[4]:35 [ ultoa::digit_value#0 ] : zp[4]:35 , -Potential registers zp[2]:39 [ ultoa_append::buffer#0 ] : zp[2]:39 , -Potential registers zp[4]:41 [ ultoa_append::sub#0 ] : zp[4]:41 , -Potential registers zp[4]:45 [ ultoa_append::return#0 ] : zp[4]:45 , +Statement [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y +Statement [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y +Statement [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:3::print_person:6 [ idx#13 print_person::person_name#4 ] main:3::print_person:8 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:3 [ idx#13 idx#16 ] +Statement [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:3::print_person:6 [ print_person::person_name#4 idx#4 ] main:3::print_person:8 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:8 [ idx#4 ] +Statement [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:3::print_person:6 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:3::print_person:8 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:6 [ print_person::i#2 print_person::i#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:7 [ idx#14 idx#5 idx#6 ] +Statement [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:3::print_person:6 [ idx#14 ] main:3::print_person:8 [ idx#14 ] ) always clobbers reg byte a +Statement [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:3::print_person:6 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:3::print_person:8 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a +Statement [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y +Statement [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y +Statement [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:3::print_person:6 [ idx#13 print_person::person_name#4 ] main:3::print_person:8 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a +Statement [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:3::print_person:6 [ print_person::person_name#4 idx#4 ] main:3::print_person:8 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a +Statement [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:3::print_person:6 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:3::print_person:8 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a +Statement [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:3::print_person:6 [ idx#14 ] main:3::print_person:8 [ idx#14 ] ) always clobbers reg byte a +Statement [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:3::print_person:6 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:3::print_person:8 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a +Potential registers zp[1]:2 [ print_person::person_id#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:3 [ idx#13 idx#16 ] : zp[1]:3 , reg byte x , reg byte y , +Potential registers zp[2]:4 [ print_person::person_name#4 ] : zp[2]:4 , +Potential registers zp[1]:6 [ print_person::i#2 print_person::i#1 ] : zp[1]:6 , reg byte x , reg byte y , +Potential registers zp[1]:7 [ idx#14 idx#5 idx#6 ] : zp[1]:7 , reg byte x , reg byte y , +Potential registers zp[1]:8 [ idx#4 ] : zp[1]:8 , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [ultoa_append] 259: zp[4]:22 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] 203: zp[1]:26 [ ultoa_append::digit#2 ultoa_append::digit#1 ] 35.5: zp[4]:41 [ ultoa_append::sub#0 ] 22: zp[4]:45 [ ultoa_append::return#0 ] 1.62: zp[2]:39 [ ultoa_append::buffer#0 ] -Uplift Scope [ultoa] 41.93: zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] 36.07: zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] 25.14: zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] 22: zp[1]:34 [ ultoa::$11 ] 16.5: zp[1]:19 [ ultoa::started#2 ultoa::started#4 ] 6.6: zp[4]:35 [ ultoa::digit_value#0 ] 4: zp[1]:31 [ ultoa::$4 ] 4: zp[2]:32 [ ultoa::buffer#3 ] -Uplift Scope [] 29.73: zp[2]:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] 26.13: zp[2]:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -Uplift Scope [print_str] 41.5: zp[2]:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -Uplift Scope [print_dword_decimal] 4: zp[4]:27 [ print_dword_decimal::w#0 ] -Uplift Scope [print_person] 2: zp[4]:2 [ print_person::person_id#2 ] 0.4: zp[2]:6 [ print_person::person_initials#2 ] -Uplift Scope [RADIX] -Uplift Scope [print_ln] -Uplift Scope [print_char] +Uplift Scope [print_person] 33: zp[1]:6 [ print_person::i#2 print_person::i#1 ] 2.2: zp[2]:4 [ print_person::person_name#4 ] 2: zp[1]:2 [ print_person::person_id#2 ] +Uplift Scope [] 24.75: zp[1]:7 [ idx#14 idx#5 idx#6 ] 4: zp[1]:3 [ idx#13 idx#16 ] 3: zp[1]:8 [ idx#4 ] Uplift Scope [Person] Uplift Scope [main] -Uplifting [ultoa_append] best 13397 combination zp[4]:22 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ] zp[4]:41 [ ultoa_append::sub#0 ] zp[4]:45 [ ultoa_append::return#0 ] zp[2]:39 [ ultoa_append::buffer#0 ] -Uplifting [ultoa] best 13263 combination zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] reg byte a [ ultoa::$11 ] reg byte x [ ultoa::started#2 ultoa::started#4 ] zp[4]:35 [ ultoa::digit_value#0 ] reg byte a [ ultoa::$4 ] zp[2]:32 [ ultoa::buffer#3 ] -Uplifting [] best 13263 combination zp[2]:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] zp[2]:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -Uplifting [print_str] best 13263 combination zp[2]:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -Uplifting [print_dword_decimal] best 13263 combination zp[4]:27 [ print_dword_decimal::w#0 ] -Uplifting [print_person] best 13263 combination zp[4]:2 [ print_person::person_id#2 ] zp[2]:6 [ print_person::person_initials#2 ] -Uplifting [RADIX] best 13263 combination -Uplifting [print_ln] best 13263 combination -Uplifting [print_char] best 13263 combination -Uplifting [Person] best 13263 combination -Uplifting [main] best 13263 combination -Attempting to uplift remaining variables inzp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] -Uplifting [ultoa] best 13263 combination zp[1]:14 [ ultoa::digit#2 ultoa::digit#1 ] -Coalescing zero page register [ zp[4]:2 [ print_person::person_id#2 ] ] with [ zp[4]:27 [ print_dword_decimal::w#0 ] ] - score: 1 -Coalescing zero page register [ zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ] ] with [ zp[4]:22 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] ] - score: 1 -Coalescing zero page register [ zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] ] with [ zp[4]:45 [ ultoa_append::return#0 ] ] - score: 1 -Coalescing zero page register [ zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ] ] with [ zp[2]:32 [ ultoa::buffer#3 ] ] - score: 1 -Coalescing zero page register [ zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ultoa::buffer#3 ] ] with [ zp[2]:39 [ ultoa_append::buffer#0 ] ] - score: 1 -Coalescing zero page register [ zp[4]:35 [ ultoa::digit_value#0 ] ] with [ zp[4]:41 [ ultoa_append::sub#0 ] ] - score: 1 -Coalescing zero page register [ zp[4]:2 [ print_person::person_id#2 print_dword_decimal::w#0 ] ] with [ zp[4]:15 [ ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ] ] - score: 1 -Coalescing zero page register [ zp[2]:20 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 ] ] with [ zp[2]:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] ] -Allocated (was zp[2]:12) zp[2]:10 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -Allocated (was zp[1]:14) zp[1]:12 [ ultoa::digit#2 ultoa::digit#1 ] -Allocated (was zp[2]:20) zp[2]:13 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -Allocated (was zp[4]:35) zp[4]:15 [ ultoa::digit_value#0 ultoa_append::sub#0 ] +Uplifting [print_person] best 577 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp[2]:4 [ print_person::person_name#4 ] reg byte x [ print_person::person_id#2 ] +Uplifting [] best 495 combination reg byte x [ idx#14 idx#5 idx#6 ] reg byte y [ idx#13 idx#16 ] reg byte x [ idx#4 ] +Uplifting [Person] best 495 combination +Uplifting [main] best 495 combination +Allocated (was zp[2]:4) zp[2]:2 [ print_person::person_name#4 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments // Example of a struct containing an array +// Works because the struct is only handled as a value // Upstart .pc = $801 "Basic" :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels - .const jesper_id = $1b244 - .const henry_id = $4466d - .label print_char_cursor = $a - .label print_line_cursor = 8 + .label SCREEN = $400 + .const jesper_id = 4 + .const henriette_id = 7 // @begin __bbegin: - // [1] phi from @begin to @1 [phi:@begin->@1] + // [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 +!: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- + // [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 +!: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- + // [2] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 // @1 __b1: - // [2] call main - // [4] phi from @1 to main [phi:@1->main] + // [3] call main + // [5] phi from @1 to main [phi:@1->main] main_from___b1: jsr main - // [3] phi from @1 to @end [phi:@1->@end] + // [4] phi from @1 to @end [phi:@1->@end] __bend_from___b1: jmp __bend // @end __bend: // main main: { - // [5] call print_person - // [9] phi from main to print_person [phi:main->print_person] + // [6] call print_person + // [10] phi from main to print_person [phi:main->print_person] print_person_from_main: - // [9] phi (byte*) print_line_cursor#20 = (byte*) 1024 [phi:main->print_person#0] -- pbuz1=pbuc1 - lda #<$400 - sta.z print_line_cursor - lda #>$400 - sta.z print_line_cursor+1 - // [9] phi (byte*) print_person::person_initials#2 = (const byte*) jesper_initials [phi:main->print_person#1] -- pbuz1=pbuc1 - lda #jesper_initials - sta.z print_person.person_initials+1 - // [9] phi (byte*) print_char_cursor#39 = (byte*) 1024 [phi:main->print_person#2] -- pbuz1=pbuc1 - lda #<$400 - sta.z print_char_cursor - lda #>$400 - sta.z print_char_cursor+1 - // [9] phi (dword) print_person::person_id#2 = (const dword) jesper_id [phi:main->print_person#3] -- vduz1=vduc1 - lda #jesper_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>jesper_id>>$10 - sta.z print_person.person_id+3 + // [10] phi (byte*) print_person::person_name#4 = (const byte*) jesper_name [phi:main->print_person#0] -- pbuz1=pbuc1 + lda #jesper_name + sta.z print_person.person_name+1 + // [10] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1 + ldy #0 + // [10] phi (byte) print_person::person_id#2 = (const byte) jesper_id [phi:main->print_person#2] -- vbuxx=vbuc1 + ldx #jesper_id jsr print_person + // [7] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: jmp __b1 // main::@1 __b1: - // [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 - lda.z print_line_cursor - sta.z print_char_cursor - lda.z print_line_cursor+1 - sta.z print_char_cursor+1 - // [7] call print_person - // [9] phi from main::@1 to print_person [phi:main::@1->print_person] + // [8] call print_person + // [10] phi from main::@1 to print_person [phi:main::@1->print_person] print_person_from___b1: - // [9] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#1 [phi:main::@1->print_person#0] -- register_copy - // [9] phi (byte*) print_person::person_initials#2 = (const byte*) henry_initials [phi:main::@1->print_person#1] -- pbuz1=pbuc1 - lda #henry_initials - sta.z print_person.person_initials+1 - // [9] phi (byte*) print_char_cursor#39 = (byte*) print_char_cursor#47 [phi:main::@1->print_person#2] -- register_copy - // [9] phi (dword) print_person::person_id#2 = (const dword) henry_id [phi:main::@1->print_person#3] -- vduz1=vduc1 - lda #henry_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>henry_id>>$10 - sta.z print_person.person_id+3 + // [10] phi (byte*) print_person::person_name#4 = (const byte*) henriette_name [phi:main::@1->print_person#0] -- pbuz1=pbuc1 + lda #henriette_name + sta.z print_person.person_name+1 + // [10] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy + // [10] phi (byte) print_person::person_id#2 = (const byte) henriette_id [phi:main::@1->print_person#2] -- vbuxx=vbuc1 + ldx #henriette_id jsr print_person jmp __breturn // main::@return __breturn: - // [8] return + // [9] return rts } // print_person -// print_person(dword zeropage(2) person_id, byte* zeropage(6) person_initials) +// print_person(byte register(X) person_id, byte* zp(2) person_name) print_person: { - .label person_id = 2 - .label person_initials = 6 - // [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 - // [11] call print_dword_decimal - jsr print_dword_decimal - // [12] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] + .label person_name = 2 + // [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx + lda DIGIT,x + sta SCREEN,y + // [12] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy + tya + tax + inx + // [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 + lda #' ' + sta SCREEN,x + // [14] (byte) idx#5 ← ++ (byte) idx#4 -- vbuxx=_inc_vbuxx + inx + // [15] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] __b1_from_print_person: + // [15] phi (byte) idx#14 = (byte) idx#5 [phi:print_person->print_person::@1#0] -- register_copy + // [15] phi (byte) print_person::i#2 = (byte) 0 [phi:print_person->print_person::@1#1] -- vbuyy=vbuc1 + ldy #0 jmp __b1 // print_person::@1 __b1: - // [13] call print_char - jsr print_char - jmp __b2 - // print_person::@2 - __b2: - // [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 -- pbuz1=pbuz2 - lda.z person_initials - sta.z print_str.str - lda.z person_initials+1 - sta.z print_str.str+1 - // [15] call print_str - // [24] phi from print_person::@2 to print_str [phi:print_person::@2->print_str] - print_str_from___b2: - // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#25 [phi:print_person::@2->print_str#0] -- register_copy - // [24] phi (byte*) print_str::str#5 = (byte*) print_str::str#2 [phi:print_person::@2->print_str#1] -- register_copy - jsr print_str - // [16] phi from print_person::@2 to print_person::@3 [phi:print_person::@2->print_person::@3] - __b3_from___b2: + // [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 -- vbuc1_neq_pbuz1_derefidx_vbuyy_then_la1 + lda (person_name),y + cmp #0 + bne __b2 jmp __b3 // print_person::@3 __b3: - // [17] call print_ln - // [19] phi from print_person::@3 to print_ln [phi:print_person::@3->print_ln] - print_ln_from___b3: - jsr print_ln + // [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 + lda #' ' + sta SCREEN,x + // [18] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx + txa + tay + iny jmp __breturn // print_person::@return __breturn: - // [18] return + // [19] return rts -} - // print_ln -// Print a newline -print_ln: { - // [20] 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: - // [20] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#20 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy - jmp __b1 - // print_ln::@1 - __b1: - // [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 -- pbuz1=pbuz1_plus_vbuc1 - lda #$28 - clc - adc.z print_line_cursor - sta.z print_line_cursor - bcc !+ - inc.z print_line_cursor+1 - !: - // [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 - lda.z print_line_cursor+1 - cmp.z print_char_cursor+1 - bcc __b1_from___b1 - bne !+ - lda.z print_line_cursor - cmp.z print_char_cursor - bcc __b1_from___b1 - !: - jmp __breturn - // print_ln::@return - __breturn: - // [23] return - rts -} - // print_str -// Print a zero-terminated string -// print_str(byte* zeropage($d) str) -print_str: { - .label str = $d - // [25] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] - __b1_from_print_str: - __b1_from___b2: - // [25] phi (byte*) print_char_cursor#18 = (byte*) print_char_cursor#41 [phi:print_str/print_str::@2->print_str::@1#0] -- register_copy - // [25] phi (byte*) print_str::str#3 = (byte*) print_str::str#5 [phi:print_str/print_str::@2->print_str::@1#1] -- register_copy - jmp __b1 - // print_str::@1 - __b1: - // [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 - ldy #0 - lda (str),y - cmp #0 - bne __b2 - jmp __breturn - // print_str::@return - __breturn: - // [27] return - rts - // print_str::@2 + // print_person::@2 __b2: - // [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) -- _deref_pbuz1=_deref_pbuz2 - ldy #0 - lda (str),y - ldy #0 - sta (print_char_cursor),y - // [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - // [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 -- pbuz1=_inc_pbuz1 - inc.z str - bne !+ - inc.z str+1 - !: - jmp __b1_from___b2 -} - // print_char -// Print a single char -print_char: { - .const ch = ' ' - // [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 -- _deref_pbuz1=vbuc1 - lda #ch - ldy #0 - sta (print_char_cursor),y - // [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - jmp __breturn - // print_char::@return - __breturn: - // [33] return - rts -} - // print_dword_decimal -// Print a dword as DECIMAL -// print_dword_decimal(dword zeropage(2) w) -print_dword_decimal: { - .label w = 2 - // [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 - // [35] call ultoa - // [39] phi from print_dword_decimal to ultoa [phi:print_dword_decimal->ultoa] - ultoa_from_print_dword_decimal: - jsr ultoa - // [36] phi from print_dword_decimal to print_dword_decimal::@1 [phi:print_dword_decimal->print_dword_decimal::@1] - __b1_from_print_dword_decimal: - jmp __b1 - // print_dword_decimal::@1 - __b1: - // [37] call print_str - // [24] phi from print_dword_decimal::@1 to print_str [phi:print_dword_decimal::@1->print_str] - print_str_from___b1: - // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#39 [phi:print_dword_decimal::@1->print_str#0] -- register_copy - // [24] phi (byte*) print_str::str#5 = (const byte*) decimal_digits_long [phi:print_dword_decimal::@1->print_str#1] -- pbuz1=pbuc1 - lda #decimal_digits_long - sta.z print_str.str+1 - jsr print_str - jmp __breturn - // print_dword_decimal::@return - __breturn: - // [38] return - rts -} - // ultoa -// Converts unsigned number value to a string representing it in RADIX format. -// If the leading digits are zero they are not included in the string. -// - value : The number to be converted to RADIX -// - buffer : receives the string representing the number and zero-termination. -// - radix : The radix to convert the number to (from the enum RADIX) -// ultoa(dword zeropage(2) value, byte* zeropage($d) buffer) -ultoa: { - .const max_digits = $a - .label digit_value = $f - .label buffer = $d - .label digit = $c - .label value = 2 - // [40] phi from ultoa to ultoa::@1 [phi:ultoa->ultoa::@1] - __b1_from_ultoa: - // [40] phi (byte*) ultoa::buffer#11 = (const byte*) decimal_digits_long [phi:ultoa->ultoa::@1#0] -- pbuz1=pbuc1 - lda #decimal_digits_long - sta.z buffer+1 - // [40] phi (byte) ultoa::started#2 = (byte) 0 [phi:ultoa->ultoa::@1#1] -- vbuxx=vbuc1 - ldx #0 - // [40] phi (dword) ultoa::value#2 = (dword) ultoa::value#1 [phi:ultoa->ultoa::@1#2] -- register_copy - // [40] phi (byte) ultoa::digit#2 = (byte) 0 [phi:ultoa->ultoa::@1#3] -- vbuz1=vbuc1 - lda #0 - sta.z digit - jmp __b1 - // ultoa::@1 - __b1: - // [41] if((byte) ultoa::digit#2<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 -- vbuz1_lt_vbuc1_then_la1 - lda.z digit - cmp #max_digits-1 - bcc __b2 - jmp __b3 - // ultoa::@3 - __b3: - // [42] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#2 -- vbuaa=_byte_vduz1 - lda.z value - // [43] *((byte*) ultoa::buffer#11) ← *((const byte*) DIGITS + (byte~) ultoa::$4) -- _deref_pbuz1=pbuc1_derefidx_vbuaa - tay - lda DIGITS,y - ldy #0 - sta (buffer),y - // [44] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz1 - inc.z buffer - bne !+ - inc.z buffer+1 - !: - // [45] *((byte*) ultoa::buffer#3) ← (byte) 0 -- _deref_pbuz1=vbuc1 - lda #0 - ldy #0 - sta (buffer),y - jmp __breturn - // ultoa::@return - __breturn: - // [46] return - rts - // ultoa::@2 - __b2: - // [47] (byte~) ultoa::$11 ← (byte) ultoa::digit#2 << (byte) 2 -- vbuaa=vbuz1_rol_2 - lda.z digit - asl - asl - // [48] (dword) ultoa::digit_value#0 ← *((const dword*) RADIX_DECIMAL_VALUES_LONG + (byte~) ultoa::$11) -- vduz1=pduc1_derefidx_vbuaa - tay - lda RADIX_DECIMAL_VALUES_LONG,y - sta.z digit_value - lda RADIX_DECIMAL_VALUES_LONG+1,y - sta.z digit_value+1 - lda RADIX_DECIMAL_VALUES_LONG+2,y - sta.z digit_value+2 - lda RADIX_DECIMAL_VALUES_LONG+3,y - sta.z digit_value+3 - // [49] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 -- vbuc1_neq_vbuxx_then_la1 - cpx #0 - bne __b5 - jmp __b7 - // ultoa::@7 - __b7: - // [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 -- vduz1_ge_vduz2_then_la1 - lda.z value+3 - cmp.z digit_value+3 - bcc !+ - bne __b5 - lda.z value+2 - cmp.z digit_value+2 - bcc !+ - bne __b5 - lda.z value+1 - cmp.z digit_value+1 - bcc !+ - bne __b5 - lda.z value - cmp.z digit_value - bcs __b5 - !: - // [51] phi from ultoa::@7 to ultoa::@4 [phi:ultoa::@7->ultoa::@4] - __b4_from___b7: - // [51] phi (byte*) ultoa::buffer#14 = (byte*) ultoa::buffer#11 [phi:ultoa::@7->ultoa::@4#0] -- register_copy - // [51] phi (byte) ultoa::started#4 = (byte) ultoa::started#2 [phi:ultoa::@7->ultoa::@4#1] -- register_copy - // [51] phi (dword) ultoa::value#6 = (dword) ultoa::value#2 [phi:ultoa::@7->ultoa::@4#2] -- register_copy - jmp __b4 - // ultoa::@4 - __b4: - // [52] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#2 -- vbuz1=_inc_vbuz1 - inc.z digit - // [40] phi from ultoa::@4 to ultoa::@1 [phi:ultoa::@4->ultoa::@1] - __b1_from___b4: - // [40] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#14 [phi:ultoa::@4->ultoa::@1#0] -- register_copy - // [40] phi (byte) ultoa::started#2 = (byte) ultoa::started#4 [phi:ultoa::@4->ultoa::@1#1] -- register_copy - // [40] phi (dword) ultoa::value#2 = (dword) ultoa::value#6 [phi:ultoa::@4->ultoa::@1#2] -- register_copy - // [40] phi (byte) ultoa::digit#2 = (byte) ultoa::digit#1 [phi:ultoa::@4->ultoa::@1#3] -- register_copy - jmp __b1 - // ultoa::@5 - __b5: - // [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 - // [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 - // [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 - // [56] call ultoa_append - // [60] phi from ultoa::@5 to ultoa_append [phi:ultoa::@5->ultoa_append] - ultoa_append_from___b5: - jsr ultoa_append - // [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 - jmp __b6 - // ultoa::@6 - __b6: - // [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 - // [59] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz1 - inc.z buffer - bne !+ - inc.z buffer+1 - !: - // [51] phi from ultoa::@6 to ultoa::@4 [phi:ultoa::@6->ultoa::@4] - __b4_from___b6: - // [51] phi (byte*) ultoa::buffer#14 = (byte*) ultoa::buffer#4 [phi:ultoa::@6->ultoa::@4#0] -- register_copy - // [51] phi (byte) ultoa::started#4 = (byte) 1 [phi:ultoa::@6->ultoa::@4#1] -- vbuxx=vbuc1 - ldx #1 - // [51] phi (dword) ultoa::value#6 = (dword) ultoa::value#0 [phi:ultoa::@6->ultoa::@4#2] -- register_copy - jmp __b4 -} - // ultoa_append -// Used to convert a single digit of an unsigned number value to a string representation -// Counts a single digit up from '0' as long as the value is larger than sub. -// Each time the digit is increased sub is subtracted from value. -// - buffer : pointer to the char that receives the digit -// - value : The value where the digit will be derived from -// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. -// (For decimal the subs used are 10000, 1000, 100, 10, 1) -// returns : the value reduced by sub * digit so that it is less than sub. -// ultoa_append(byte* zeropage($d) buffer, dword zeropage(2) value, dword zeropage($f) sub) -ultoa_append: { - .label buffer = $d - .label value = 2 - .label sub = $f - .label return = 2 - // [61] phi from ultoa_append to ultoa_append::@1 [phi:ultoa_append->ultoa_append::@1] - __b1_from_ultoa_append: - // [61] phi (byte) ultoa_append::digit#2 = (byte) 0 [phi:ultoa_append->ultoa_append::@1#0] -- vbuxx=vbuc1 - ldx #0 - // [61] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#0 [phi:ultoa_append->ultoa_append::@1#1] -- register_copy - jmp __b1 - // ultoa_append::@1 - __b1: - // [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -- vduz1_ge_vduz2_then_la1 - lda.z value+3 - cmp.z sub+3 - bcc !+ - bne __b2 - lda.z value+2 - cmp.z sub+2 - bcc !+ - bne __b2 - lda.z value+1 - cmp.z sub+1 - bcc !+ - bne __b2 - lda.z value - cmp.z sub - bcs __b2 - !: - jmp __b3 - // ultoa_append::@3 - __b3: - // [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) -- _deref_pbuz1=pbuc1_derefidx_vbuxx - lda DIGITS,x - ldy #0 - sta (buffer),y - jmp __breturn - // ultoa_append::@return - __breturn: - // [64] return - rts - // ultoa_append::@2 - __b2: - // [65] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 -- vbuxx=_inc_vbuxx + // [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) -- pbuc1_derefidx_vbuxx=pbuz1_derefidx_vbuyy + lda (person_name),y + sta SCREEN,x + // [21] (byte) idx#6 ← ++ (byte) idx#14 -- vbuxx=_inc_vbuxx inx - // [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 -- vduz1=vduz1_minus_vduz2 - lda.z value - sec - sbc.z sub - sta.z value - lda.z value+1 - sbc.z sub+1 - sta.z value+1 - lda.z value+2 - sbc.z sub+2 - sta.z value+2 - lda.z value+3 - sbc.z sub+3 - sta.z value+3 - // [61] phi from ultoa_append::@2 to ultoa_append::@1 [phi:ultoa_append::@2->ultoa_append::@1] + // [22] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 -- vbuyy=_inc_vbuyy + iny + // [15] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1] __b1_from___b2: - // [61] phi (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#1 [phi:ultoa_append::@2->ultoa_append::@1#0] -- register_copy - // [61] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#1 [phi:ultoa_append::@2->ultoa_append::@1#1] -- register_copy + // [15] phi (byte) idx#14 = (byte) idx#6 [phi:print_person::@2->print_person::@1#0] -- register_copy + // [15] phi (byte) print_person::i#2 = (byte) print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy jmp __b1 } // File Data - // The digits used for numbers - DIGITS: .text "0123456789abcdef" - // Values of decimal digits - RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a - // Digits used for storing the decimal word - decimal_digits_long: .fill $b, 0 - jesper_initials: .text "jg" + DIGIT: .text "0123456789" .byte 0 - henry_initials: .text "hg" + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 + __0: .text "jesper" .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 @@ -2614,670 +700,219 @@ Removing instruction jmp __bend Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b1 -Removing instruction jmp __b2 -Removing instruction jmp __b3 -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 __b3 -Removing instruction jmp __breturn -Removing instruction jmp __b7 -Removing instruction jmp __b4 -Removing instruction jmp __b6 -Removing instruction jmp __b1 Removing instruction jmp __b3 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination -Removing instruction ldy #0 -Replacing instruction lda #0 with TXA -Replacing instruction ldy #0 with TAY -Succesful ASM optimization Pass5UnnecesaryLoadElimination -Replacing label __bbegin with __b1 -Replacing label __b1_from___b1 with __b1 -Replacing label __b1_from___b1 with __b1 -Replacing label __b1_from___b2 with __b1 -Removing instruction __bbegin: Removing instruction __b1_from___bbegin: Removing instruction main_from___b1: Removing instruction __bend_from___b1: -Removing instruction __b1_from_print_person: -Removing instruction __b3_from___b2: -Removing instruction print_ln_from___b3: -Removing instruction __b1_from_print_ln: -Removing instruction __b1_from___b1: -Removing instruction __b1_from_print_str: -Removing instruction __b1_from___b2: -Removing instruction __b1_from_print_dword_decimal: -Removing instruction print_str_from___b1: -Removing instruction __b4_from___b7: -Removing instruction ultoa_append_from___b5: +Removing instruction __b1_from_main: +Removing instruction print_person_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __b1: Removing instruction __bend: Removing instruction print_person_from_main: Removing instruction __b1: -Removing instruction print_person_from___b1: Removing instruction __breturn: -Removing instruction __b1: -Removing instruction __b2: -Removing instruction print_str_from___b2: -Removing instruction __b3: -Removing instruction __breturn: -Removing instruction __breturn: -Removing instruction __breturn: -Removing instruction __breturn: -Removing instruction ultoa_from_print_dword_decimal: -Removing instruction __b1: -Removing instruction __breturn: -Removing instruction __b1_from_ultoa: -Removing instruction __b3: -Removing instruction __breturn: -Removing instruction __b7: -Removing instruction __b1_from___b4: -Removing instruction __b6: -Removing instruction __b4_from___b6: -Removing instruction __b1_from_ultoa_append: +Removing instruction __b1_from_print_person: Removing instruction __b3: Removing instruction __breturn: Removing instruction __b1_from___b2: Succesful ASM optimization Pass5UnusedLabelElimination -Updating BasicUpstart to call main directly -Removing instruction jsr main -Succesful ASM optimization Pass5SkipBegin -Removing instruction __b1: -Succesful ASM optimization Pass5UnusedLabelElimination +Adding RTS to root block +Succesful ASM optimization Pass5AddMainRts FINAL SYMBOL TABLE +(const byte*) $0[(number) $40] = (string) "jesper" +(const byte*) $1[(number) $40] = (string) "henriette" (label) @1 (label) @begin (label) @end -(const byte*) DIGITS = (string) "0123456789abcdef"z -(dword) Person::id -(const byte*) Person::initials = { fill( 3, 0) } -(const byte) RADIX::BINARY = (number) 2 -(const byte) RADIX::DECIMAL = (number) $a -(const byte) RADIX::HEXADECIMAL = (number) $10 -(const byte) RADIX::OCTAL = (number) 8 -(const dword*) RADIX_DECIMAL_VALUES_LONG = { (dword) $3b9aca00, (dword) $5f5e100, (dword) $989680, (dword) $f4240, (dword) $186a0, (dword) $2710, (dword) $3e8, (dword) $64, (dword) $a } -(const byte*) decimal_digits_long = { fill( $b, 0) } -(const dword) henry_id = (dword) $4466d -(const byte*) henry_initials = (string) "hg" -(const dword) jesper_id = (dword) $1b244 -(const byte*) jesper_initials = (string) "jg" +(const byte*) DIGIT[] = (string) "0123456789" +(byte) Person::id +(const byte*) Person::name[(number) $40] = { fill( $40, 0) } +(const byte*) SCREEN = (byte*) 1024 +(const byte) henriette_id = (byte) 7 +(const byte*) henriette_name[(number) $40] = { fill( $40, 0) } +(byte) idx +(byte) idx#13 reg byte y 3.0 +(byte) idx#14 reg byte x 9.75 +(byte) idx#16 reg byte y 1.0 +(byte) idx#4 reg byte x 3.0 +(byte) idx#5 reg byte x 4.0 +(byte) idx#6 reg byte x 11.0 +(const byte) jesper_id = (byte) 4 +(const byte*) jesper_name[(number) $40] = { fill( $40, 0) } (void()) main() (label) main::@1 (label) main::@return -(void()) print_char((byte) print_char::ch) -(label) print_char::@return -(byte) print_char::ch -(const byte) print_char::ch#0 ch = (byte) ' ' -(byte*) print_char_cursor -(byte*) print_char_cursor#1 print_char_cursor zp[2]:10 11.0 -(byte*) print_char_cursor#18 print_char_cursor zp[2]:10 3.333333333333333 -(byte*) print_char_cursor#25 print_char_cursor zp[2]:10 1.0 -(byte*) print_char_cursor#39 print_char_cursor zp[2]:10 0.8 -(byte*) print_char_cursor#41 print_char_cursor zp[2]:10 6.0 -(byte*) print_char_cursor#47 print_char_cursor zp[2]:10 4.0 -(void()) print_dword_decimal((dword) print_dword_decimal::w) -(label) print_dword_decimal::@1 -(label) print_dword_decimal::@return -(dword) print_dword_decimal::w -(dword) print_dword_decimal::w#0 w zp[4]:2 4.0 -(byte*) print_line_cursor -(byte*) print_line_cursor#1 print_line_cursor zp[2]:8 5.285714285714286 -(byte*) print_line_cursor#20 print_line_cursor zp[2]:8 0.4444444444444444 -(byte*) print_line_cursor#9 print_line_cursor zp[2]:8 24.0 -(void()) print_ln() -(label) print_ln::@1 -(label) print_ln::@return -(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 (label) print_person::@return +(byte) print_person::i +(byte) print_person::i#1 reg byte y 22.0 +(byte) print_person::i#2 reg byte y 11.0 (struct Person) print_person::person -(dword) print_person::person_id -(dword) print_person::person_id#2 person_id zp[4]:2 2.0 -(const byte*) print_person::person_initials -(byte*) print_person::person_initials#2 person_initials zp[2]:6 0.4 -(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[2]:13 22.0 -(byte*) print_str::str#2 str zp[2]:13 4.0 -(byte*) print_str::str#3 str zp[2]:13 11.5 -(byte*) print_str::str#5 str zp[2]:13 4.0 -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -(byte~) ultoa::$11 reg byte a 22.0 -(byte~) ultoa::$4 reg byte a 4.0 -(label) ultoa::@1 -(label) ultoa::@2 -(label) ultoa::@3 -(label) ultoa::@4 -(label) ultoa::@5 -(label) ultoa::@6 -(label) ultoa::@7 -(label) ultoa::@return -(byte*) ultoa::buffer -(byte*) ultoa::buffer#11 buffer zp[2]:13 3.4285714285714284 -(byte*) ultoa::buffer#14 buffer zp[2]:13 16.5 -(byte*) ultoa::buffer#3 buffer zp[2]:13 4.0 -(byte*) ultoa::buffer#4 buffer zp[2]:13 22.0 -(byte) ultoa::digit -(byte) ultoa::digit#1 digit zp[1]:12 22.0 -(byte) ultoa::digit#2 digit zp[1]:12 3.142857142857143 -(dword) ultoa::digit_value -(dword) ultoa::digit_value#0 digit_value zp[4]:15 6.6000000000000005 -(dword*) ultoa::digit_values -(byte) ultoa::max_digits -(const byte) ultoa::max_digits#1 max_digits = (byte) $a -(byte) ultoa::radix -(byte) ultoa::started -(byte) ultoa::started#2 reg byte x 5.5 -(byte) ultoa::started#4 reg byte x 11.0 -(dword) ultoa::value -(dword) ultoa::value#0 value zp[4]:2 11.0 -(dword) ultoa::value#1 value zp[4]:2 2.0 -(dword) ultoa::value#2 value zp[4]:2 6.571428571428571 -(dword) ultoa::value#6 value zp[4]:2 16.5 -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -(label) ultoa_append::@1 -(label) ultoa_append::@2 -(label) ultoa_append::@3 -(label) ultoa_append::@return -(byte*) ultoa_append::buffer -(byte*) ultoa_append::buffer#0 buffer zp[2]:13 1.625 -(byte) ultoa_append::digit -(byte) ultoa_append::digit#1 reg byte x 101.0 -(byte) ultoa_append::digit#2 reg byte x 102.0 -(dword) ultoa_append::return -(dword) ultoa_append::return#0 return zp[4]:2 22.0 -(dword) ultoa_append::sub -(dword) ultoa_append::sub#0 sub zp[4]:15 35.5 -(dword) ultoa_append::value -(dword) ultoa_append::value#0 value zp[4]:2 4.333333333333333 -(dword) ultoa_append::value#1 value zp[4]:2 202.0 -(dword) ultoa_append::value#2 value zp[4]:2 52.66666666666666 +(byte) print_person::person_id +(byte) print_person::person_id#2 reg byte x 2.0 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 -zp[4]:2 [ print_person::person_id#2 print_dword_decimal::w#0 ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ] -zp[2]:6 [ print_person::person_initials#2 ] -zp[2]:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] -zp[2]:10 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -zp[1]:12 [ ultoa::digit#2 ultoa::digit#1 ] -reg byte x [ ultoa::started#2 ultoa::started#4 ] -zp[2]:13 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ] -reg byte a [ ultoa::$4 ] -reg byte a [ ultoa::$11 ] -zp[4]:15 [ ultoa::digit_value#0 ultoa_append::sub#0 ] +reg byte x [ print_person::person_id#2 ] +reg byte y [ idx#13 idx#16 ] +zp[2]:2 [ print_person::person_name#4 ] +reg byte y [ print_person::i#2 print_person::i#1 ] +reg byte x [ idx#14 idx#5 idx#6 ] +reg byte x [ idx#4 ] FINAL ASSEMBLER -Score: 11194 +Score: 426 // File Comments // Example of a struct containing an array +// Works because the struct is only handled as a value // Upstart .pc = $801 "Basic" -:BasicUpstart(main) +:BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels - .const jesper_id = $1b244 - .const henry_id = $4466d - .label print_char_cursor = $a - .label print_line_cursor = 8 + .label SCREEN = $400 + .const jesper_id = 4 + .const henriette_id = 7 // @begin - // [1] phi from @begin to @1 [phi:@begin->@1] +__bbegin: + // jesper = { 4, "jesper" } + // [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 +!: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- + // henriette = { 7, "henriette" } + // [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 +!: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- + // [2] phi from @begin to @1 [phi:@begin->@1] // @1 - // [2] call main - // [4] phi from @1 to main [phi:@1->main] - // [3] phi from @1 to @end [phi:@1->@end] + // [3] call main + // [5] phi from @1 to main [phi:@1->main] + jsr main + rts + // [4] phi from @1 to @end [phi:@1->@end] // @end // main main: { // print_person(jesper) - // [5] call print_person - // [9] phi from main to print_person [phi:main->print_person] - // [9] phi (byte*) print_line_cursor#20 = (byte*) 1024 [phi:main->print_person#0] -- pbuz1=pbuc1 - lda #<$400 - sta.z print_line_cursor - lda #>$400 - sta.z print_line_cursor+1 - // [9] phi (byte*) print_person::person_initials#2 = (const byte*) jesper_initials [phi:main->print_person#1] -- pbuz1=pbuc1 - lda #jesper_initials - sta.z print_person.person_initials+1 - // [9] phi (byte*) print_char_cursor#39 = (byte*) 1024 [phi:main->print_person#2] -- pbuz1=pbuc1 - lda #<$400 - sta.z print_char_cursor - lda #>$400 - sta.z print_char_cursor+1 - // [9] phi (dword) print_person::person_id#2 = (const dword) jesper_id [phi:main->print_person#3] -- vduz1=vduc1 - lda #jesper_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>jesper_id>>$10 - sta.z print_person.person_id+3 + // [6] call print_person + // [10] phi from main to print_person [phi:main->print_person] + // [10] phi (byte*) print_person::person_name#4 = (const byte*) jesper_name [phi:main->print_person#0] -- pbuz1=pbuc1 + lda #jesper_name + sta.z print_person.person_name+1 + // [10] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1 + ldy #0 + // [10] phi (byte) print_person::person_id#2 = (const byte) jesper_id [phi:main->print_person#2] -- vbuxx=vbuc1 + ldx #jesper_id jsr print_person + // [7] phi from main to main::@1 [phi:main->main::@1] // main::@1 - // [6] (byte*) print_char_cursor#47 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 - lda.z print_line_cursor - sta.z print_char_cursor - lda.z print_line_cursor+1 - sta.z print_char_cursor+1 - // print_person(henry) - // [7] call print_person - // [9] phi from main::@1 to print_person [phi:main::@1->print_person] - // [9] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#1 [phi:main::@1->print_person#0] -- register_copy - // [9] phi (byte*) print_person::person_initials#2 = (const byte*) henry_initials [phi:main::@1->print_person#1] -- pbuz1=pbuc1 - lda #henry_initials - sta.z print_person.person_initials+1 - // [9] phi (byte*) print_char_cursor#39 = (byte*) print_char_cursor#47 [phi:main::@1->print_person#2] -- register_copy - // [9] phi (dword) print_person::person_id#2 = (const dword) henry_id [phi:main::@1->print_person#3] -- vduz1=vduc1 - lda #henry_id - sta.z print_person.person_id+1 - lda #>$10 - sta.z print_person.person_id+2 - lda #>henry_id>>$10 - sta.z print_person.person_id+3 + // print_person(henriette) + // [8] call print_person + // [10] phi from main::@1 to print_person [phi:main::@1->print_person] + // [10] phi (byte*) print_person::person_name#4 = (const byte*) henriette_name [phi:main::@1->print_person#0] -- pbuz1=pbuc1 + lda #henriette_name + sta.z print_person.person_name+1 + // [10] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy + // [10] phi (byte) print_person::person_id#2 = (const byte) henriette_id [phi:main::@1->print_person#2] -- vbuxx=vbuc1 + ldx #henriette_id jsr print_person // main::@return // } - // [8] return + // [9] return rts } // print_person -// print_person(dword zeropage(2) person_id, byte* zeropage(6) person_initials) +// print_person(byte register(X) person_id, byte* zp(2) person_name) print_person: { - .label person_id = 2 - .label person_initials = 6 - // print_dword_decimal(person.id) - // [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 - // [11] call print_dword_decimal - jsr print_dword_decimal - // [12] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] - // print_person::@1 - // print_char(' ') - // [13] call print_char - jsr print_char - // print_person::@2 - // print_str(person.initials) - // [14] (byte*) print_str::str#2 ← (byte*) print_person::person_initials#2 -- pbuz1=pbuz2 - lda.z person_initials - sta.z print_str.str - lda.z person_initials+1 - sta.z print_str.str+1 - // [15] call print_str - // [24] phi from print_person::@2 to print_str [phi:print_person::@2->print_str] - // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#25 [phi:print_person::@2->print_str#0] -- register_copy - // [24] phi (byte*) print_str::str#5 = (byte*) print_str::str#2 [phi:print_person::@2->print_str#1] -- register_copy - jsr print_str - // [16] phi from print_person::@2 to print_person::@3 [phi:print_person::@2->print_person::@3] - // print_person::@3 - // print_ln() - // [17] call print_ln - // [19] phi from print_person::@3 to print_ln [phi:print_person::@3->print_ln] - jsr print_ln - // print_person::@return - // } - // [18] return - rts -} - // print_ln -// Print a newline -print_ln: { - // [20] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] - // [20] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#20 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy - // print_ln::@1 - __b1: - // print_line_cursor + $28 - // [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 -- pbuz1=pbuz1_plus_vbuc1 - lda #$28 - clc - adc.z print_line_cursor - sta.z print_line_cursor - bcc !+ - inc.z print_line_cursor+1 - !: - // while (print_line_cursorprint_str::@1] - // [25] phi (byte*) print_char_cursor#18 = (byte*) print_char_cursor#41 [phi:print_str/print_str::@2->print_str::@1#0] -- register_copy - // [25] phi (byte*) print_str::str#3 = (byte*) print_str::str#5 [phi:print_str/print_str::@2->print_str::@1#1] -- register_copy - // print_str::@1 - __b1: - // while(*str) - // [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 + .label person_name = 2 + // SCREEN[idx++] = DIGIT[person.id] + // [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx + lda DIGIT,x + sta SCREEN,y + // SCREEN[idx++] = DIGIT[person.id]; + // [12] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy + tya + tax + inx + // SCREEN[idx++] = ' ' + // [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 + lda #' ' + sta SCREEN,x + // SCREEN[idx++] = ' '; + // [14] (byte) idx#5 ← ++ (byte) idx#4 -- vbuxx=_inc_vbuxx + inx + // [15] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] + // [15] phi (byte) idx#14 = (byte) idx#5 [phi:print_person->print_person::@1#0] -- register_copy + // [15] phi (byte) print_person::i#2 = (byte) 0 [phi:print_person->print_person::@1#1] -- vbuyy=vbuc1 ldy #0 - lda (str),y + // print_person::@1 + __b1: + // for(byte i=0; person.name[i]; i++) + // [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 -- vbuc1_neq_pbuz1_derefidx_vbuyy_then_la1 + lda (person_name),y cmp #0 bne __b2 - // print_str::@return - // } - // [27] return - rts - // print_str::@2 - __b2: - // *(print_char_cursor++) = *(str++) - // [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) -- _deref_pbuz1=_deref_pbuz2 - ldy #0 - lda (str),y - sta (print_char_cursor),y - // *(print_char_cursor++) = *(str++); - // [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - // [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 -- pbuz1=_inc_pbuz1 - inc.z str - bne !+ - inc.z str+1 - !: - jmp __b1 -} - // print_char -// Print a single char -print_char: { - .const ch = ' ' - // *(print_char_cursor++) = ch - // [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 -- _deref_pbuz1=vbuc1 - lda #ch - ldy #0 - sta (print_char_cursor),y - // *(print_char_cursor++) = ch; - // [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 - inc.z print_char_cursor - bne !+ - inc.z print_char_cursor+1 - !: - // print_char::@return - // } - // [33] return - rts -} - // print_dword_decimal -// Print a dword as DECIMAL -// print_dword_decimal(dword zeropage(2) w) -print_dword_decimal: { - .label w = 2 - // ultoa(w, decimal_digits_long, DECIMAL) - // [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 - // [35] call ultoa - // [39] phi from print_dword_decimal to ultoa [phi:print_dword_decimal->ultoa] - jsr ultoa - // [36] phi from print_dword_decimal to print_dword_decimal::@1 [phi:print_dword_decimal->print_dword_decimal::@1] - // print_dword_decimal::@1 - // print_str(decimal_digits_long) - // [37] call print_str - // [24] phi from print_dword_decimal::@1 to print_str [phi:print_dword_decimal::@1->print_str] - // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#39 [phi:print_dword_decimal::@1->print_str#0] -- register_copy - // [24] phi (byte*) print_str::str#5 = (const byte*) decimal_digits_long [phi:print_dword_decimal::@1->print_str#1] -- pbuz1=pbuc1 - lda #decimal_digits_long - sta.z print_str.str+1 - jsr print_str - // print_dword_decimal::@return - // } - // [38] return - rts -} - // ultoa -// Converts unsigned number value to a string representing it in RADIX format. -// If the leading digits are zero they are not included in the string. -// - value : The number to be converted to RADIX -// - buffer : receives the string representing the number and zero-termination. -// - radix : The radix to convert the number to (from the enum RADIX) -// ultoa(dword zeropage(2) value, byte* zeropage($d) buffer) -ultoa: { - .const max_digits = $a - .label digit_value = $f - .label buffer = $d - .label digit = $c - .label value = 2 - // [40] phi from ultoa to ultoa::@1 [phi:ultoa->ultoa::@1] - // [40] phi (byte*) ultoa::buffer#11 = (const byte*) decimal_digits_long [phi:ultoa->ultoa::@1#0] -- pbuz1=pbuc1 - lda #decimal_digits_long - sta.z buffer+1 - // [40] phi (byte) ultoa::started#2 = (byte) 0 [phi:ultoa->ultoa::@1#1] -- vbuxx=vbuc1 - ldx #0 - // [40] phi (dword) ultoa::value#2 = (dword) ultoa::value#1 [phi:ultoa->ultoa::@1#2] -- register_copy - // [40] phi (byte) ultoa::digit#2 = (byte) 0 [phi:ultoa->ultoa::@1#3] -- vbuz1=vbuc1 + // print_person::@3 + // SCREEN[idx++] = ' ' + // [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 + lda #' ' + sta SCREEN,x + // SCREEN[idx++] = ' '; + // [18] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx txa - sta.z digit - // ultoa::@1 - __b1: - // for( char digit=0; digit= digit_value) - // [49] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 -- vbuc1_neq_vbuxx_then_la1 - cpx #0 - bne __b5 - // ultoa::@7 - // [50] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@5 -- vduz1_ge_vduz2_then_la1 - lda.z value+3 - cmp.z digit_value+3 - bcc !+ - bne __b5 - lda.z value+2 - cmp.z digit_value+2 - bcc !+ - bne __b5 - lda.z value+1 - cmp.z digit_value+1 - bcc !+ - bne __b5 - lda.z value - cmp.z digit_value - bcs __b5 - !: - // [51] phi from ultoa::@7 to ultoa::@4 [phi:ultoa::@7->ultoa::@4] - // [51] phi (byte*) ultoa::buffer#14 = (byte*) ultoa::buffer#11 [phi:ultoa::@7->ultoa::@4#0] -- register_copy - // [51] phi (byte) ultoa::started#4 = (byte) ultoa::started#2 [phi:ultoa::@7->ultoa::@4#1] -- register_copy - // [51] phi (dword) ultoa::value#6 = (dword) ultoa::value#2 [phi:ultoa::@7->ultoa::@4#2] -- register_copy - // ultoa::@4 - __b4: - // for( char digit=0; digitultoa::@1] - // [40] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#14 [phi:ultoa::@4->ultoa::@1#0] -- register_copy - // [40] phi (byte) ultoa::started#2 = (byte) ultoa::started#4 [phi:ultoa::@4->ultoa::@1#1] -- register_copy - // [40] phi (dword) ultoa::value#2 = (dword) ultoa::value#6 [phi:ultoa::@4->ultoa::@1#2] -- register_copy - // [40] phi (byte) ultoa::digit#2 = (byte) ultoa::digit#1 [phi:ultoa::@4->ultoa::@1#3] -- register_copy - jmp __b1 - // ultoa::@5 - __b5: - // ultoa_append(buffer++, value, digit_value) - // [53] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#11 - // [54] (dword) ultoa_append::value#0 ← (dword) ultoa::value#2 - // [55] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#0 - // [56] call ultoa_append - // [60] phi from ultoa::@5 to ultoa_append [phi:ultoa::@5->ultoa_append] - jsr ultoa_append - // ultoa_append(buffer++, value, digit_value) - // [57] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 - // ultoa::@6 - // value = ultoa_append(buffer++, value, digit_value) - // [58] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 - // value = ultoa_append(buffer++, value, digit_value); - // [59] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz1 - inc.z buffer - bne !+ - inc.z buffer+1 - !: - // [51] phi from ultoa::@6 to ultoa::@4 [phi:ultoa::@6->ultoa::@4] - // [51] phi (byte*) ultoa::buffer#14 = (byte*) ultoa::buffer#4 [phi:ultoa::@6->ultoa::@4#0] -- register_copy - // [51] phi (byte) ultoa::started#4 = (byte) 1 [phi:ultoa::@6->ultoa::@4#1] -- vbuxx=vbuc1 - ldx #1 - // [51] phi (dword) ultoa::value#6 = (dword) ultoa::value#0 [phi:ultoa::@6->ultoa::@4#2] -- register_copy - jmp __b4 -} - // ultoa_append -// Used to convert a single digit of an unsigned number value to a string representation -// Counts a single digit up from '0' as long as the value is larger than sub. -// Each time the digit is increased sub is subtracted from value. -// - buffer : pointer to the char that receives the digit -// - value : The value where the digit will be derived from -// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. -// (For decimal the subs used are 10000, 1000, 100, 10, 1) -// returns : the value reduced by sub * digit so that it is less than sub. -// ultoa_append(byte* zeropage($d) buffer, dword zeropage(2) value, dword zeropage($f) sub) -ultoa_append: { - .label buffer = $d - .label value = 2 - .label sub = $f - .label return = 2 - // [61] phi from ultoa_append to ultoa_append::@1 [phi:ultoa_append->ultoa_append::@1] - // [61] phi (byte) ultoa_append::digit#2 = (byte) 0 [phi:ultoa_append->ultoa_append::@1#0] -- vbuxx=vbuc1 - ldx #0 - // [61] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#0 [phi:ultoa_append->ultoa_append::@1#1] -- register_copy - // ultoa_append::@1 - __b1: - // while (value >= sub) - // [62] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -- vduz1_ge_vduz2_then_la1 - lda.z value+3 - cmp.z sub+3 - bcc !+ - bne __b2 - lda.z value+2 - cmp.z sub+2 - bcc !+ - bne __b2 - lda.z value+1 - cmp.z sub+1 - bcc !+ - bne __b2 - lda.z value - cmp.z sub - bcs __b2 - !: - // ultoa_append::@3 - // *buffer = DIGITS[digit] - // [63] *((byte*) ultoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) ultoa_append::digit#2) -- _deref_pbuz1=pbuc1_derefidx_vbuxx - lda DIGITS,x - ldy #0 - sta (buffer),y - // ultoa_append::@return - // } - // [64] return - rts - // ultoa_append::@2 - __b2: - // digit++; - // [65] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 -- vbuxx=_inc_vbuxx + // SCREEN[idx++] = person.name[i] + // [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) -- pbuc1_derefidx_vbuxx=pbuz1_derefidx_vbuyy + lda (person_name),y + sta SCREEN,x + // SCREEN[idx++] = person.name[i]; + // [21] (byte) idx#6 ← ++ (byte) idx#14 -- vbuxx=_inc_vbuxx inx - // value -= sub - // [66] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 -- vduz1=vduz1_minus_vduz2 - lda.z value - sec - sbc.z sub - sta.z value - lda.z value+1 - sbc.z sub+1 - sta.z value+1 - lda.z value+2 - sbc.z sub+2 - sta.z value+2 - lda.z value+3 - sbc.z sub+3 - sta.z value+3 - // [61] phi from ultoa_append::@2 to ultoa_append::@1 [phi:ultoa_append::@2->ultoa_append::@1] - // [61] phi (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#1 [phi:ultoa_append::@2->ultoa_append::@1#0] -- register_copy - // [61] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#1 [phi:ultoa_append::@2->ultoa_append::@1#1] -- register_copy + // for(byte i=0; person.name[i]; i++) + // [22] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 -- vbuyy=_inc_vbuyy + iny + // [15] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1] + // [15] phi (byte) idx#14 = (byte) idx#6 [phi:print_person::@2->print_person::@1#0] -- register_copy + // [15] phi (byte) print_person::i#2 = (byte) print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy jmp __b1 } // File Data - // The digits used for numbers - DIGITS: .text "0123456789abcdef" - // Values of decimal digits - RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a - // Digits used for storing the decimal word - decimal_digits_long: .fill $b, 0 - jesper_initials: .text "jg" + DIGIT: .text "0123456789" .byte 0 - henry_initials: .text "hg" + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 + __0: .text "jesper" .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 diff --git a/src/test/ref/struct-11.sym b/src/test/ref/struct-11.sym index f865b28a0..2935c84ad 100644 --- a/src/test/ref/struct-11.sym +++ b/src/test/ref/struct-11.sym @@ -1,125 +1,43 @@ +(const byte*) $0[(number) $40] = (string) "jesper" +(const byte*) $1[(number) $40] = (string) "henriette" (label) @1 (label) @begin (label) @end -(const byte*) DIGITS = (string) "0123456789abcdef"z -(dword) Person::id -(const byte*) Person::initials = { fill( 3, 0) } -(const byte) RADIX::BINARY = (number) 2 -(const byte) RADIX::DECIMAL = (number) $a -(const byte) RADIX::HEXADECIMAL = (number) $10 -(const byte) RADIX::OCTAL = (number) 8 -(const dword*) RADIX_DECIMAL_VALUES_LONG = { (dword) $3b9aca00, (dword) $5f5e100, (dword) $989680, (dword) $f4240, (dword) $186a0, (dword) $2710, (dword) $3e8, (dword) $64, (dword) $a } -(const byte*) decimal_digits_long = { fill( $b, 0) } -(const dword) henry_id = (dword) $4466d -(const byte*) henry_initials = (string) "hg" -(const dword) jesper_id = (dword) $1b244 -(const byte*) jesper_initials = (string) "jg" +(const byte*) DIGIT[] = (string) "0123456789" +(byte) Person::id +(const byte*) Person::name[(number) $40] = { fill( $40, 0) } +(const byte*) SCREEN = (byte*) 1024 +(const byte) henriette_id = (byte) 7 +(const byte*) henriette_name[(number) $40] = { fill( $40, 0) } +(byte) idx +(byte) idx#13 reg byte y 3.0 +(byte) idx#14 reg byte x 9.75 +(byte) idx#16 reg byte y 1.0 +(byte) idx#4 reg byte x 3.0 +(byte) idx#5 reg byte x 4.0 +(byte) idx#6 reg byte x 11.0 +(const byte) jesper_id = (byte) 4 +(const byte*) jesper_name[(number) $40] = { fill( $40, 0) } (void()) main() (label) main::@1 (label) main::@return -(void()) print_char((byte) print_char::ch) -(label) print_char::@return -(byte) print_char::ch -(const byte) print_char::ch#0 ch = (byte) ' ' -(byte*) print_char_cursor -(byte*) print_char_cursor#1 print_char_cursor zp[2]:10 11.0 -(byte*) print_char_cursor#18 print_char_cursor zp[2]:10 3.333333333333333 -(byte*) print_char_cursor#25 print_char_cursor zp[2]:10 1.0 -(byte*) print_char_cursor#39 print_char_cursor zp[2]:10 0.8 -(byte*) print_char_cursor#41 print_char_cursor zp[2]:10 6.0 -(byte*) print_char_cursor#47 print_char_cursor zp[2]:10 4.0 -(void()) print_dword_decimal((dword) print_dword_decimal::w) -(label) print_dword_decimal::@1 -(label) print_dword_decimal::@return -(dword) print_dword_decimal::w -(dword) print_dword_decimal::w#0 w zp[4]:2 4.0 -(byte*) print_line_cursor -(byte*) print_line_cursor#1 print_line_cursor zp[2]:8 5.285714285714286 -(byte*) print_line_cursor#20 print_line_cursor zp[2]:8 0.4444444444444444 -(byte*) print_line_cursor#9 print_line_cursor zp[2]:8 24.0 -(void()) print_ln() -(label) print_ln::@1 -(label) print_ln::@return -(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 (label) print_person::@return +(byte) print_person::i +(byte) print_person::i#1 reg byte y 22.0 +(byte) print_person::i#2 reg byte y 11.0 (struct Person) print_person::person -(dword) print_person::person_id -(dword) print_person::person_id#2 person_id zp[4]:2 2.0 -(const byte*) print_person::person_initials -(byte*) print_person::person_initials#2 person_initials zp[2]:6 0.4 -(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[2]:13 22.0 -(byte*) print_str::str#2 str zp[2]:13 4.0 -(byte*) print_str::str#3 str zp[2]:13 11.5 -(byte*) print_str::str#5 str zp[2]:13 4.0 -(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) -(byte~) ultoa::$11 reg byte a 22.0 -(byte~) ultoa::$4 reg byte a 4.0 -(label) ultoa::@1 -(label) ultoa::@2 -(label) ultoa::@3 -(label) ultoa::@4 -(label) ultoa::@5 -(label) ultoa::@6 -(label) ultoa::@7 -(label) ultoa::@return -(byte*) ultoa::buffer -(byte*) ultoa::buffer#11 buffer zp[2]:13 3.4285714285714284 -(byte*) ultoa::buffer#14 buffer zp[2]:13 16.5 -(byte*) ultoa::buffer#3 buffer zp[2]:13 4.0 -(byte*) ultoa::buffer#4 buffer zp[2]:13 22.0 -(byte) ultoa::digit -(byte) ultoa::digit#1 digit zp[1]:12 22.0 -(byte) ultoa::digit#2 digit zp[1]:12 3.142857142857143 -(dword) ultoa::digit_value -(dword) ultoa::digit_value#0 digit_value zp[4]:15 6.6000000000000005 -(dword*) ultoa::digit_values -(byte) ultoa::max_digits -(const byte) ultoa::max_digits#1 max_digits = (byte) $a -(byte) ultoa::radix -(byte) ultoa::started -(byte) ultoa::started#2 reg byte x 5.5 -(byte) ultoa::started#4 reg byte x 11.0 -(dword) ultoa::value -(dword) ultoa::value#0 value zp[4]:2 11.0 -(dword) ultoa::value#1 value zp[4]:2 2.0 -(dword) ultoa::value#2 value zp[4]:2 6.571428571428571 -(dword) ultoa::value#6 value zp[4]:2 16.5 -(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) -(label) ultoa_append::@1 -(label) ultoa_append::@2 -(label) ultoa_append::@3 -(label) ultoa_append::@return -(byte*) ultoa_append::buffer -(byte*) ultoa_append::buffer#0 buffer zp[2]:13 1.625 -(byte) ultoa_append::digit -(byte) ultoa_append::digit#1 reg byte x 101.0 -(byte) ultoa_append::digit#2 reg byte x 102.0 -(dword) ultoa_append::return -(dword) ultoa_append::return#0 return zp[4]:2 22.0 -(dword) ultoa_append::sub -(dword) ultoa_append::sub#0 sub zp[4]:15 35.5 -(dword) ultoa_append::value -(dword) ultoa_append::value#0 value zp[4]:2 4.333333333333333 -(dword) ultoa_append::value#1 value zp[4]:2 202.0 -(dword) ultoa_append::value#2 value zp[4]:2 52.66666666666666 +(byte) print_person::person_id +(byte) print_person::person_id#2 reg byte x 2.0 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 -zp[4]:2 [ print_person::person_id#2 print_dword_decimal::w#0 ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ] -zp[2]:6 [ print_person::person_initials#2 ] -zp[2]:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] -zp[2]:10 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#47 print_char_cursor#25 print_char_cursor#1 ] -zp[1]:12 [ ultoa::digit#2 ultoa::digit#1 ] -reg byte x [ ultoa::started#2 ultoa::started#4 ] -zp[2]:13 [ ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] -reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ] -reg byte a [ ultoa::$4 ] -reg byte a [ ultoa::$11 ] -zp[4]:15 [ ultoa::digit_value#0 ultoa_append::sub#0 ] +reg byte x [ print_person::person_id#2 ] +reg byte y [ idx#13 idx#16 ] +zp[2]:2 [ print_person::person_name#4 ] +reg byte y [ print_person::i#2 print_person::i#1 ] +reg byte x [ idx#14 idx#5 idx#6 ] +reg byte x [ idx#4 ] diff --git a/src/test/ref/struct-12.asm b/src/test/ref/struct-12.asm index 77971eced..4dd0b2d85 100644 --- a/src/test/ref/struct-12.asm +++ b/src/test/ref/struct-12.asm @@ -4,16 +4,30 @@ :BasicUpstart(main) .pc = $80d "Program" .label SCREEN = $400 + .label idx = 2 main: { .const jesper_id = 4 .const henriette_id = 7 + ldy #$40 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- lda #jesper_name sta.z print_person.person_name+1 - ldy #0 + lda #0 + sta.z idx ldx #jesper_id jsr print_person + ldy #$40 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- lda #henriette_name @@ -21,18 +35,16 @@ main: { ldx #henriette_id jsr print_person rts - jesper_name: .text "jesper" - .byte 0 - henriette_name: .text "henriette" - .byte 0 + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 } -// print_person(byte register(X) person_id, byte* zeropage(2) person_name) +// print_person(byte register(X) person_id, byte* zp(3) person_name) print_person: { - .label person_name = 2 + .label person_name = 3 lda DIGIT,x + ldy.z idx sta SCREEN,y - tya - tax + ldx.z idx inx lda #' ' sta SCREEN,x @@ -44,9 +56,8 @@ print_person: { bne __b2 lda #' ' sta SCREEN,x - txa - tay - iny + inx + stx.z idx rts __b2: lda (person_name),y @@ -57,3 +68,9 @@ print_person: { } DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 diff --git a/src/test/ref/struct-12.cfg b/src/test/ref/struct-12.cfg index 8d7ab347c..e45ba677b 100644 --- a/src/test/ref/struct-12.cfg +++ b/src/test/ref/struct-12.cfg @@ -10,22 +10,22 @@ (void()) main() main: scope:[main] from @1 - [4] phi() + [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [5] call print_person to:main::@1 main::@1: scope:[main] from main - [6] phi() + [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [7] call print_person to:main::@return main::@return: scope:[main] from main::@1 [8] return to:@return -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 - [9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name#1 main::@1/(const byte*) main::henriette_name#1 ) + [9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name main::@1/(const byte*) main::henriette_name ) [9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) - [9] (byte) print_person::person_id#2 ← phi( main/(const byte) main::jesper_id#1 main::@1/(const byte) main::henriette_id#1 ) + [9] (byte) print_person::person_id#2 ← phi( main/(const byte) main::jesper_id main::@1/(const byte) main::henriette_id ) [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [11] (byte) idx#4 ← ++ (byte) idx#13 [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' diff --git a/src/test/ref/struct-12.log b/src/test/ref/struct-12.log index ded67e334..effffb7cf 100644 --- a/src/test/ref/struct-12.log +++ b/src/test/ref/struct-12.log @@ -1,6 +1,8 @@ Fixing struct type size struct Person to 65 Fixing struct type size struct Person to 65 Fixing struct type size struct Person to 65 +Fixing struct type SIZE_OF struct Person to 65 +Fixing struct type SIZE_OF struct Person to 65 Created struct value member variable (byte) main::jesper_id Created struct value member variable (const byte*) main::jesper_name Converted struct value to member variables (struct Person) main::jesper @@ -8,23 +10,21 @@ Created struct value member variable (byte) main::henriette_id Created struct value member variable (const byte*) main::henriette_name Converted struct value to member variables (struct Person) main::henriette Created struct value member variable (byte) print_person::person_id -Created struct value member variable (const byte*) print_person::person_name +Created struct value member variable (byte*) print_person::person_name Converted struct value to member variables (struct Person) print_person::person -Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) -Adding struct value member variable default initializer (byte) main::jesper_id ← (byte) 0 -Adding struct value member variable default initializer (const byte*) main::jesper_name ← (byte*) 0 +Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) +Adding struct value member variable copy (byte) main::jesper_id ← (byte) 4 +Adding struct value member variable copy *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (const byte*) main::jesper_name -Adding struct value member variable default initializer (byte) main::henriette_id ← (byte) 0 -Adding struct value member variable default initializer (const byte*) main::henriette_name ← (byte*) 0 +Adding struct value member variable copy (byte) main::henriette_id ← (byte) 7 +Adding struct value member variable copy *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (const byte*) main::henriette_name -Replacing struct member reference (struct Person) main::jesper.id with member unwinding reference (byte) main::jesper_id -Replacing struct member reference (struct Person) main::jesper.name with member unwinding reference (const byte*) main::jesper_name -Replacing struct member reference (struct Person) main::henriette.id with member unwinding reference (byte) main::henriette_id -Replacing struct member reference (struct Person) main::henriette.name with member unwinding reference (const byte*) main::henriette_name Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id -Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name -Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name -Warning! Adding boolean cast to non-boolean condition *((const byte*) print_person::person_name + (byte) print_person::i) +Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name +Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name +Warning! Adding boolean cast to non-boolean condition *((byte*) print_person::person_name + (byte) print_person::i) +Identified constant variable (byte) main::jesper_id +Identified constant variable (byte) main::henriette_id Culled Empty Block (label) print_person::@4 Culled Empty Block (label) print_person::@5 Culled Empty Block (label) print_person::@6 @@ -36,23 +36,17 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 (byte) idx#18 ← phi( @2/(byte) idx#20 ) - (byte) main::jesper_id#0 ← (byte) 0 - (byte*) main::jesper_name#0 ← (byte*) 0 - (byte) main::jesper_id#1 ← (number) 4 - (byte*) main::jesper_name#1 ← (const string) main::$2 - (byte) print_person::person_id#0 ← (byte) main::jesper_id#1 - (byte*) print_person::person_name#0 ← (byte*) main::jesper_name#1 + *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) + (byte) print_person::person_id#0 ← (const byte) main::jesper_id + (byte*) print_person::person_name#0 ← (const byte*) main::jesper_name call print_person to:main::@1 main::@1: scope:[main] from main (byte) idx#10 ← phi( main/(byte) idx#8 ) (byte) idx#0 ← (byte) idx#10 - (byte) main::henriette_id#0 ← (byte) 0 - (byte*) main::henriette_name#0 ← (byte*) 0 - (byte) main::henriette_id#1 ← (number) 7 - (byte*) main::henriette_name#1 ← (const string) main::$3 - (byte) print_person::person_id#1 ← (byte) main::henriette_id#1 - (byte*) print_person::person_name#1 ← (byte*) main::henriette_name#1 + *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) + (byte) print_person::person_id#1 ← (const byte) main::henriette_id + (byte*) print_person::person_name#1 ← (const byte*) main::henriette_name call print_person to:main::@2 main::@2: scope:[main] from main::@1 @@ -65,10 +59,10 @@ main::@return: scope:[main] from main::@2 return to:@return @1: scope:[] from @begin - (byte) idx#3 ← (number) 0 + (byte) idx#3 ← (byte) 0 to:@2 -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 (byte*) print_person::person_name#4 ← phi( main/(byte*) print_person::person_name#0 main::@1/(byte*) print_person::person_name#1 ) (byte) idx#13 ← phi( main/(byte) idx#18 main::@1/(byte) idx#0 ) @@ -77,7 +71,7 @@ print_person: scope:[print_person] from main main::@1 (byte) idx#4 ← ++ (byte) idx#13 *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' (byte) idx#5 ← ++ (byte) idx#4 - (byte) print_person::i#0 ← (number) 0 + (byte) print_person::i#0 ← (byte) 0 to:print_person::@1 print_person::@1: scope:[print_person] from print_person print_person::@2 (byte) idx#19 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 ) @@ -115,14 +109,16 @@ print_person::@return: scope:[print_person] from print_person::@3 @end: scope:[] from @3 SYMBOL TABLE SSA +(const byte*) $0[(number) $40] = (string) "jesper" +(const byte*) $1[(number) $40] = (string) "henriette" (label) @1 (label) @2 (label) @3 (label) @begin (label) @end -(const byte*) DIGIT = (string) "0123456789" +(const byte*) DIGIT[] = (string) "0123456789" (byte) Person::id -(const byte*) Person::name = { fill( $40, 0) } +(const byte*) Person::name[(number) $40] = { fill( $40, 0) } (const byte*) SCREEN = (byte*)(number) $400 (byte) idx (byte) idx#0 @@ -147,24 +143,14 @@ SYMBOL TABLE SSA (byte) idx#8 (byte) idx#9 (void()) main() -(const string) main::$2 = (string) "jesper" -(const string) main::$3 = (string) "henriette" (label) main::@1 (label) main::@2 (label) main::@return -(byte) main::henriette_id -(byte) main::henriette_id#0 -(byte) main::henriette_id#1 -(const byte*) main::henriette_name -(byte*) main::henriette_name#0 -(byte*) main::henriette_name#1 -(byte) main::jesper_id -(byte) main::jesper_id#0 -(byte) main::jesper_id#1 -(const byte*) main::jesper_name -(byte*) main::jesper_name#0 -(byte*) main::jesper_name#1 -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(const byte) main::henriette_id = (byte) 7 +(const byte*) main::henriette_name[(number) $40] = { fill( $40, 0) } +(const byte) main::jesper_id = (byte) 4 +(const byte*) main::jesper_name[(number) $40] = { fill( $40, 0) } +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (bool~) print_person::$0 (label) print_person::@1 (label) print_person::@2 @@ -180,35 +166,18 @@ SYMBOL TABLE SSA (byte) print_person::person_id#0 (byte) print_person::person_id#1 (byte) print_person::person_id#2 -(const byte*) print_person::person_name +(byte*) print_person::person_name (byte*) print_person::person_name#0 (byte*) print_person::person_name#1 (byte*) print_person::person_name#2 (byte*) print_person::person_name#3 (byte*) print_person::person_name#4 -Adding number conversion cast (unumber) 4 in (byte) main::jesper_id#1 ← (number) 4 -Adding number conversion cast (unumber) 7 in (byte) main::henriette_id#1 ← (number) 7 -Adding number conversion cast (unumber) 0 in (byte) idx#3 ← (number) 0 -Adding number conversion cast (unumber) 0 in (byte) print_person::i#0 ← (number) 0 Adding number conversion cast (unumber) 0 in (bool~) print_person::$0 ← (number) 0 != *((byte*) print_person::person_name#2 + (byte) print_person::i#2) Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast (byte) main::jesper_id#1 ← (unumber)(number) 4 -Inlining cast (byte) main::henriette_id#1 ← (unumber)(number) 7 -Inlining cast (byte) idx#3 ← (unumber)(number) 0 -Inlining cast (byte) print_person::i#0 ← (unumber)(number) 0 -Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 -Simplifying constant integer cast 4 -Simplifying constant integer cast 7 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 Simplifying constant integer cast 0 Successful SSA optimization PassNCastSimplification -Finalized unsigned number type (byte) 4 -Finalized unsigned number type (byte) 7 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (byte) idx#0 = (byte) idx#10 @@ -226,60 +195,43 @@ Identical Phi Values (byte) idx#1 (byte) idx#16 Identical Phi Values (byte*) print_person::person_name#2 (byte*) print_person::person_name#4 Identical Phi Values (byte) idx#17 (byte) idx#1 Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition (bool~) print_person::$0 [31] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 +Simple Condition (bool~) print_person::$0 [25] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 Successful SSA optimization Pass2ConditionalJumpSimplification -Constant (const byte) main::jesper_id#0 = 0 -Constant (const byte*) main::jesper_name#0 = (byte*) 0 -Constant (const byte) main::jesper_id#1 = 4 -Constant (const byte*) main::jesper_name#1 = main::$2 -Constant (const byte) main::henriette_id#0 = 0 -Constant (const byte*) main::henriette_name#0 = (byte*) 0 -Constant (const byte) main::henriette_id#1 = 7 -Constant (const byte*) main::henriette_name#1 = main::$3 +Constant (const byte) print_person::person_id#0 = main::jesper_id +Constant (const byte*) print_person::person_name#0 = main::jesper_name +Constant (const byte) print_person::person_id#1 = main::henriette_id +Constant (const byte*) print_person::person_name#1 = main::henriette_name Constant (const byte) idx#20 = 0 Constant (const byte) print_person::i#0 = 0 Successful SSA optimization Pass2ConstantIdentification -Constant (const byte) print_person::person_id#0 = main::jesper_id#1 -Constant (const byte*) print_person::person_name#0 = main::jesper_name#1 -Constant (const byte) print_person::person_id#1 = main::henriette_id#1 -Constant (const byte*) print_person::person_name#1 = main::henriette_name#1 -Successful SSA optimization Pass2ConstantIdentification -Eliminating unused constant (const byte) main::jesper_id#0 -Eliminating unused constant (const byte*) main::jesper_name#0 -Eliminating unused constant (const byte) main::henriette_id#0 -Eliminating unused constant (const byte*) main::henriette_name#0 -Successful SSA optimization PassNEliminateUnusedVars -Inlining constant with var siblings (const byte) print_person::i#0 Inlining constant with var siblings (const byte) print_person::person_id#0 Inlining constant with var siblings (const byte*) print_person::person_name#0 Inlining constant with var siblings (const byte) print_person::person_id#1 Inlining constant with var siblings (const byte*) print_person::person_name#1 +Inlining constant with var siblings (const byte) print_person::i#0 Inlining constant with var siblings (const byte) idx#20 Constant inlined idx#20 = (byte) 0 -Constant inlined print_person::person_id#1 = (const byte) main::henriette_id#1 -Constant inlined print_person::person_id#0 = (const byte) main::jesper_id#1 -Constant inlined main::$2 = (const byte*) main::jesper_name#1 +Constant inlined print_person::person_id#1 = (const byte) main::henriette_id +Constant inlined print_person::person_id#0 = (const byte) main::jesper_id Constant inlined print_person::i#0 = (byte) 0 -Constant inlined print_person::person_name#1 = (const byte*) main::henriette_name#1 -Constant inlined main::$3 = (const byte*) main::henriette_name#1 -Constant inlined print_person::person_name#0 = (const byte*) main::jesper_name#1 +Constant inlined print_person::person_name#1 = (const byte*) main::henriette_name +Constant inlined print_person::person_name#0 = (const byte*) main::jesper_name Successful SSA optimization Pass2ConstantInlining Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 Adding NOP phi() at start of @2 Adding NOP phi() at start of @3 Adding NOP phi() at start of @end -Adding NOP phi() at start of main Adding NOP phi() at start of main::@2 CALL GRAPH Calls in [] to main:3 -Calls in [main] to print_person:7 print_person:9 +Calls in [main] to print_person:7 print_person:10 Created 5 initial phi equivalence classes -Coalesced [8] idx#21 ← idx#16 -Coalesced [17] idx#22 ← idx#5 -Coalesced [26] print_person::i#4 ← print_person::i#1 -Coalesced [27] idx#23 ← idx#6 +Coalesced [9] idx#21 ← idx#16 +Coalesced [18] idx#22 ← idx#5 +Coalesced [27] print_person::i#4 ← print_person::i#1 +Coalesced [28] idx#23 ← idx#6 Coalesced down to 5 phi equivalence classes Culled Empty Block (label) @1 Culled Empty Block (label) @3 @@ -288,8 +240,6 @@ Renumbering block @2 to @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 -Adding NOP phi() at start of main::@1 FINAL CONTROL FLOW GRAPH @begin: scope:[] from @@ -304,22 +254,22 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] phi() + [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [5] call print_person to:main::@1 main::@1: scope:[main] from main - [6] phi() + [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [7] call print_person to:main::@return main::@return: scope:[main] from main::@1 [8] return to:@return -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 - [9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name#1 main::@1/(const byte*) main::henriette_name#1 ) + [9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name main::@1/(const byte*) main::henriette_name ) [9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) - [9] (byte) print_person::person_id#2 ← phi( main/(const byte) main::jesper_id#1 main::@1/(const byte) main::henriette_id#1 ) + [9] (byte) print_person::person_id#2 ← phi( main/(const byte) main::jesper_id main::@1/(const byte) main::henriette_id ) [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [11] (byte) idx#4 ← ++ (byte) idx#13 [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' @@ -354,18 +304,14 @@ VARIABLE REGISTER WEIGHTS (byte) idx#5 4.0 (byte) idx#6 11.0 (void()) main() -(byte) main::henriette_id -(const byte*) main::henriette_name -(byte) main::jesper_id -(const byte*) main::jesper_name -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (byte) print_person::i (byte) print_person::i#1 22.0 (byte) print_person::i#2 11.0 (struct Person) print_person::person (byte) print_person::person_id (byte) print_person::person_id#2 2.0 -(const byte*) print_person::person_name +(byte*) print_person::person_name (byte*) print_person::person_name#4 2.2 Initial phi equivalence classes @@ -411,8 +357,6 @@ __b1_from___bbegin: // @1 __b1: // [2] call main - // [4] phi from @1 to main [phi:@1->main] -main_from___b1: jsr main // [3] phi from @1 to @end [phi:@1->@end] __bend_from___b1: @@ -423,10 +367,17 @@ __bend: main: { .const jesper_id = 4 .const henriette_id = 7 + // [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- // [5] call print_person // [9] phi from main to print_person [phi:main->print_person] print_person_from_main: - // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::jesper_name#1 [phi:main->print_person#0] -- pbuz1=pbuc1 + // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::jesper_name [phi:main->print_person#0] -- pbuz1=pbuc1 lda #jesper_name @@ -434,25 +385,30 @@ main: { // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1 lda #0 sta.z idx_2 - // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id#1 [phi:main->print_person#2] -- vbuz1=vbuc1 + // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id [phi:main->print_person#2] -- vbuz1=vbuc1 lda #jesper_id sta.z print_person.person_id jsr print_person - // [6] phi from main to main::@1 [phi:main->main::@1] - __b1_from_main: jmp __b1 // main::@1 __b1: + // [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- // [7] call print_person // [9] phi from main::@1 to print_person [phi:main::@1->print_person] print_person_from___b1: - // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::henriette_name#1 [phi:main::@1->print_person#0] -- pbuz1=pbuc1 + // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::henriette_name [phi:main::@1->print_person#0] -- pbuz1=pbuc1 lda #henriette_name sta.z print_person.person_name+1 // [9] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy - // [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id#1 [phi:main::@1->print_person#2] -- vbuz1=vbuc1 + // [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id [phi:main::@1->print_person#2] -- vbuz1=vbuc1 lda #henriette_id sta.z print_person.person_id jsr print_person @@ -461,13 +417,11 @@ main: { __breturn: // [8] return rts - jesper_name: .text "jesper" - .byte 0 - henriette_name: .text "henriette" - .byte 0 + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 } // print_person -// print_person(byte zeropage(2) person_id, byte* zeropage(4) person_name) +// print_person(byte zp(2) person_id, byte* zp(4) person_name) print_person: { .label i = 6 .label person_id = 2 @@ -539,10 +493,19 @@ print_person: { // File Data DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 REGISTER UPLIFT POTENTIAL REGISTERS -Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a +Statement [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte a as potential for zp[1]:3 [ idx#13 idx#16 ] +Removing always clobbered register reg byte y as potential for zp[1]:3 [ idx#13 idx#16 ] +Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:8 [ idx#4 ] Statement [15] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a @@ -550,13 +513,15 @@ Removing always clobbered register reg byte a as potential for zp[1]:6 [ print_p Removing always clobbered register reg byte a as potential for zp[1]:7 [ idx#14 idx#5 idx#6 ] Statement [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a Statement [19] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a +Statement [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a Statement [15] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a Statement [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a Statement [19] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a Potential registers zp[1]:2 [ print_person::person_id#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:3 [ idx#13 idx#16 ] : zp[1]:3 , reg byte x , reg byte y , +Potential registers zp[1]:3 [ idx#13 idx#16 ] : zp[1]:3 , reg byte x , Potential registers zp[2]:4 [ print_person::person_name#4 ] : zp[2]:4 , Potential registers zp[1]:6 [ print_person::i#2 print_person::i#1 ] : zp[1]:6 , reg byte x , reg byte y , Potential registers zp[1]:7 [ idx#14 idx#5 idx#6 ] : zp[1]:7 , reg byte x , reg byte y , @@ -568,11 +533,14 @@ Uplift Scope [] 24.75: zp[1]:7 [ idx#14 idx#5 idx#6 ] 4: zp[1]:3 [ idx#13 idx#16 Uplift Scope [Person] Uplift Scope [main] -Uplifting [print_person] best 545 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp[2]:4 [ print_person::person_name#4 ] reg byte x [ print_person::person_id#2 ] -Uplifting [] best 463 combination reg byte x [ idx#14 idx#5 idx#6 ] reg byte y [ idx#13 idx#16 ] reg byte x [ idx#4 ] -Uplifting [Person] best 463 combination -Uplifting [main] best 463 combination -Allocated (was zp[2]:4) zp[2]:2 [ print_person::person_name#4 ] +Uplifting [print_person] best 577 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp[2]:4 [ print_person::person_name#4 ] reg byte x [ print_person::person_id#2 ] +Uplifting [] best 499 combination reg byte x [ idx#14 idx#5 idx#6 ] zp[1]:3 [ idx#13 idx#16 ] reg byte x [ idx#4 ] +Uplifting [Person] best 499 combination +Uplifting [main] best 499 combination +Attempting to uplift remaining variables inzp[1]:3 [ idx#13 idx#16 ] +Uplifting [] best 499 combination zp[1]:3 [ idx#13 idx#16 ] +Allocated (was zp[1]:3) zp[1]:2 [ idx#13 idx#16 ] +Allocated (was zp[2]:4) zp[2]:3 [ print_person::person_name#4 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -584,6 +552,7 @@ ASSEMBLER BEFORE OPTIMIZATION .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 + .label idx = 2 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -592,8 +561,6 @@ __b1_from___bbegin: // @1 __b1: // [2] call main - // [4] phi from @1 to main [phi:@1->main] -main_from___b1: jsr main // [3] phi from @1 to @end [phi:@1->@end] __bend_from___b1: @@ -604,34 +571,47 @@ __bend: main: { .const jesper_id = 4 .const henriette_id = 7 + // [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- // [5] call print_person // [9] phi from main to print_person [phi:main->print_person] print_person_from_main: - // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::jesper_name#1 [phi:main->print_person#0] -- pbuz1=pbuc1 + // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::jesper_name [phi:main->print_person#0] -- pbuz1=pbuc1 lda #jesper_name sta.z print_person.person_name+1 - // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1 - ldy #0 - // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id#1 [phi:main->print_person#2] -- vbuxx=vbuc1 + // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1 + lda #0 + sta.z idx + // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id [phi:main->print_person#2] -- vbuxx=vbuc1 ldx #jesper_id jsr print_person - // [6] phi from main to main::@1 [phi:main->main::@1] - __b1_from_main: jmp __b1 // main::@1 __b1: + // [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- // [7] call print_person // [9] phi from main::@1 to print_person [phi:main::@1->print_person] print_person_from___b1: - // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::henriette_name#1 [phi:main::@1->print_person#0] -- pbuz1=pbuc1 + // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::henriette_name [phi:main::@1->print_person#0] -- pbuz1=pbuc1 lda #henriette_name sta.z print_person.person_name+1 // [9] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy - // [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id#1 [phi:main::@1->print_person#2] -- vbuxx=vbuc1 + // [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id [phi:main::@1->print_person#2] -- vbuxx=vbuc1 ldx #henriette_id jsr print_person jmp __breturn @@ -639,21 +619,19 @@ main: { __breturn: // [8] return rts - jesper_name: .text "jesper" - .byte 0 - henriette_name: .text "henriette" - .byte 0 + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 } // print_person -// print_person(byte register(X) person_id, byte* zeropage(2) person_name) +// print_person(byte register(X) person_id, byte* zp(3) person_name) print_person: { - .label person_name = 2 - // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx + .label person_name = 3 + // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuxx lda DIGIT,x + ldy.z idx sta SCREEN,y - // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy - tya - tax + // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuz1 + ldx.z idx inx // [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 lda #' ' @@ -678,10 +656,9 @@ print_person: { // [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 lda #' ' sta SCREEN,x - // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx - txa - tay - iny + // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuxx + inx + stx.z idx jmp __breturn // print_person::@return __breturn: @@ -705,6 +682,12 @@ print_person: { // File Data DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 @@ -718,14 +701,12 @@ Succesful ASM optimization Pass5NextJumpElimination Replacing label __bbegin with __b1 Removing instruction __bbegin: Removing instruction __b1_from___bbegin: -Removing instruction main_from___b1: Removing instruction __bend_from___b1: -Removing instruction __b1_from_main: -Removing instruction print_person_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __bend: Removing instruction print_person_from_main: Removing instruction __b1: +Removing instruction print_person_from___b1: Removing instruction __breturn: Removing instruction __b1_from_print_person: Removing instruction __b3: @@ -739,32 +720,30 @@ Removing instruction __b1: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE +(const byte*) $0[(number) $40] = (string) "jesper" +(const byte*) $1[(number) $40] = (string) "henriette" (label) @1 (label) @begin (label) @end -(const byte*) DIGIT = (string) "0123456789" +(const byte*) DIGIT[] = (string) "0123456789" (byte) Person::id -(const byte*) Person::name = { fill( $40, 0) } +(const byte*) Person::name[(number) $40] = { fill( $40, 0) } (const byte*) SCREEN = (byte*) 1024 (byte) idx -(byte) idx#13 reg byte y 3.0 +(byte) idx#13 idx zp[1]:2 3.0 (byte) idx#14 reg byte x 9.75 -(byte) idx#16 reg byte y 1.0 +(byte) idx#16 idx zp[1]:2 1.0 (byte) idx#4 reg byte x 3.0 (byte) idx#5 reg byte x 4.0 (byte) idx#6 reg byte x 11.0 (void()) main() (label) main::@1 (label) main::@return -(byte) main::henriette_id -(const byte) main::henriette_id#1 henriette_id = (byte) 7 -(const byte*) main::henriette_name -(const byte*) main::henriette_name#1 henriette_name = (string) "henriette" -(byte) main::jesper_id -(const byte) main::jesper_id#1 jesper_id = (byte) 4 -(const byte*) main::jesper_name -(const byte*) main::jesper_name#1 jesper_name = (string) "jesper" -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(const byte) main::henriette_id = (byte) 7 +(const byte*) main::henriette_name[(number) $40] = { fill( $40, 0) } +(const byte) main::jesper_id = (byte) 4 +(const byte*) main::jesper_name[(number) $40] = { fill( $40, 0) } +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 @@ -775,19 +754,19 @@ FINAL SYMBOL TABLE (struct Person) print_person::person (byte) print_person::person_id (byte) print_person::person_id#2 reg byte x 2.0 -(const byte*) print_person::person_name -(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 person_name zp[2]:3 2.2 reg byte x [ print_person::person_id#2 ] -reg byte y [ idx#13 idx#16 ] -zp[2]:2 [ print_person::person_name#4 ] +zp[1]:2 [ idx#13 idx#16 ] +zp[2]:3 [ print_person::person_name#4 ] reg byte y [ print_person::i#2 print_person::i#1 ] reg byte x [ idx#14 idx#5 idx#6 ] reg byte x [ idx#4 ] FINAL ASSEMBLER -Score: 382 +Score: 418 // File Comments // Example of a struct containing an array @@ -798,65 +777,79 @@ Score: 382 .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 + .label idx = 2 // @begin // [1] phi from @begin to @1 [phi:@begin->@1] // @1 // [2] call main - // [4] phi from @1 to main [phi:@1->main] // [3] phi from @1 to @end [phi:@1->@end] // @end // main main: { .const jesper_id = 4 .const henriette_id = 7 + // jesper = { 4, "jesper" } + // [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- // print_person(jesper) // [5] call print_person // [9] phi from main to print_person [phi:main->print_person] - // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::jesper_name#1 [phi:main->print_person#0] -- pbuz1=pbuc1 + // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::jesper_name [phi:main->print_person#0] -- pbuz1=pbuc1 lda #jesper_name sta.z print_person.person_name+1 - // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1 - ldy #0 - // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id#1 [phi:main->print_person#2] -- vbuxx=vbuc1 + // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1 + lda #0 + sta.z idx + // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id [phi:main->print_person#2] -- vbuxx=vbuc1 ldx #jesper_id jsr print_person - // [6] phi from main to main::@1 [phi:main->main::@1] // main::@1 + // henriette = { 7, "henriette" } + // [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$40 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- // print_person(henriette) // [7] call print_person // [9] phi from main::@1 to print_person [phi:main::@1->print_person] - // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::henriette_name#1 [phi:main::@1->print_person#0] -- pbuz1=pbuc1 + // [9] phi (byte*) print_person::person_name#4 = (const byte*) main::henriette_name [phi:main::@1->print_person#0] -- pbuz1=pbuc1 lda #henriette_name sta.z print_person.person_name+1 // [9] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy - // [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id#1 [phi:main::@1->print_person#2] -- vbuxx=vbuc1 + // [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id [phi:main::@1->print_person#2] -- vbuxx=vbuc1 ldx #henriette_id jsr print_person // main::@return // } // [8] return rts - jesper_name: .text "jesper" - .byte 0 - henriette_name: .text "henriette" - .byte 0 + jesper_name: .fill $40, 0 + henriette_name: .fill $40, 0 } // print_person -// print_person(byte register(X) person_id, byte* zeropage(2) person_name) +// print_person(byte register(X) person_id, byte* zp(3) person_name) print_person: { - .label person_name = 2 + .label person_name = 3 // SCREEN[idx++] = DIGIT[person.id] - // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx + // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuxx lda DIGIT,x + ldy.z idx sta SCREEN,y // SCREEN[idx++] = DIGIT[person.id]; - // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy - tya - tax + // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuz1 + ldx.z idx inx // SCREEN[idx++] = ' ' // [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 @@ -882,10 +875,9 @@ print_person: { lda #' ' sta SCREEN,x // SCREEN[idx++] = ' '; - // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx - txa - tay - iny + // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuxx + inx + stx.z idx // print_person::@return // } // [18] return @@ -910,4 +902,10 @@ print_person: { // File Data DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill $39, 0 + __1: .text "henriette" + .byte 0 + .fill $36, 0 diff --git a/src/test/ref/struct-12.sym b/src/test/ref/struct-12.sym index 4ec2fb1fd..9b5278b9a 100644 --- a/src/test/ref/struct-12.sym +++ b/src/test/ref/struct-12.sym @@ -1,29 +1,27 @@ +(const byte*) $0[(number) $40] = (string) "jesper" +(const byte*) $1[(number) $40] = (string) "henriette" (label) @1 (label) @begin (label) @end -(const byte*) DIGIT = (string) "0123456789" +(const byte*) DIGIT[] = (string) "0123456789" (byte) Person::id -(const byte*) Person::name = { fill( $40, 0) } +(const byte*) Person::name[(number) $40] = { fill( $40, 0) } (const byte*) SCREEN = (byte*) 1024 (byte) idx -(byte) idx#13 reg byte y 3.0 +(byte) idx#13 idx zp[1]:2 3.0 (byte) idx#14 reg byte x 9.75 -(byte) idx#16 reg byte y 1.0 +(byte) idx#16 idx zp[1]:2 1.0 (byte) idx#4 reg byte x 3.0 (byte) idx#5 reg byte x 4.0 (byte) idx#6 reg byte x 11.0 (void()) main() (label) main::@1 (label) main::@return -(byte) main::henriette_id -(const byte) main::henriette_id#1 henriette_id = (byte) 7 -(const byte*) main::henriette_name -(const byte*) main::henriette_name#1 henriette_name = (string) "henriette" -(byte) main::jesper_id -(const byte) main::jesper_id#1 jesper_id = (byte) 4 -(const byte*) main::jesper_name -(const byte*) main::jesper_name#1 jesper_name = (string) "jesper" -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(const byte) main::henriette_id = (byte) 7 +(const byte*) main::henriette_name[(number) $40] = { fill( $40, 0) } +(const byte) main::jesper_id = (byte) 4 +(const byte*) main::jesper_name[(number) $40] = { fill( $40, 0) } +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 @@ -34,12 +32,12 @@ (struct Person) print_person::person (byte) print_person::person_id (byte) print_person::person_id#2 reg byte x 2.0 -(const byte*) print_person::person_name -(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 person_name zp[2]:3 2.2 reg byte x [ print_person::person_id#2 ] -reg byte y [ idx#13 idx#16 ] -zp[2]:2 [ print_person::person_name#4 ] +zp[1]:2 [ idx#13 idx#16 ] +zp[2]:3 [ print_person::person_name#4 ] reg byte y [ print_person::i#2 print_person::i#1 ] reg byte x [ idx#14 idx#5 idx#6 ] reg byte x [ idx#4 ] diff --git a/src/test/ref/struct-13.log b/src/test/ref/struct-13.log index 11d78dac2..4364ddb09 100644 --- a/src/test/ref/struct-13.log +++ b/src/test/ref/struct-13.log @@ -1,5 +1,5 @@ -Adding struct value member variable default initializer *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 -Adding struct value member variable default initializer *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 +Adding struct value member variable copy *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 +Adding struct value member variable copy *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) Replacing struct member reference (struct Point) point.y with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) diff --git a/src/test/ref/struct-15.log b/src/test/ref/struct-15.log index 41bbb1187..73cae0118 100644 --- a/src/test/ref/struct-15.log +++ b/src/test/ref/struct-15.log @@ -1,5 +1,5 @@ -Adding struct value member variable default initializer *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 -Adding struct value member variable default initializer *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) diff --git a/src/test/ref/struct-17.log b/src/test/ref/struct-17.log index 0b6101a51..c2c895a8e 100644 --- a/src/test/ref/struct-17.log +++ b/src/test/ref/struct-17.log @@ -1,5 +1,5 @@ -Adding struct value member variable default initializer *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← {} -Adding struct value member variable default initializer *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← {} +Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← { x: (byte) 0, y: (byte) 0 } +Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← { x: (byte) 0, y: (byte) 0 } Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) diff --git a/src/test/ref/struct-19.log b/src/test/ref/struct-19.log index 69fab3019..6f28c023d 100644 --- a/src/test/ref/struct-19.log +++ b/src/test/ref/struct-19.log @@ -1,5 +1,5 @@ -Adding struct value member variable default initializer *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← {} -Adding struct value member variable default initializer *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← {} +Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← { x: (byte) 0, y: (byte) 0 } +Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← { x: (byte) 0, y: (byte) 0 } Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4 diff --git a/src/test/ref/struct-2.log b/src/test/ref/struct-2.log index 699422d84..85dd05827 100644 --- a/src/test/ref/struct-2.log +++ b/src/test/ref/struct-2.log @@ -4,10 +4,10 @@ Converted struct value to member variables (struct Point) point1 Created struct value member variable (byte) point2_x Created struct value member variable (byte) point2_y Converted struct value to member variables (struct Point) point2 -Adding struct value member variable default initializer (byte) point1_x ← (byte) 0 -Adding struct value member variable default initializer (byte) point1_y ← (byte) 0 -Adding struct value member variable default initializer (byte) point2_x ← (byte) 0 -Adding struct value member variable default initializer (byte) point2_y ← (byte) 0 +Adding struct value member variable copy (byte) point1_x ← (byte) 0 +Adding struct value member variable copy (byte) point1_y ← (byte) 0 +Adding struct value member variable copy (byte) point2_x ← (byte) 0 +Adding struct value member variable copy (byte) point2_y ← (byte) 0 Adding struct value member variable copy (byte) point2_x ← (byte) point1_x Adding struct value member variable copy (byte) point2_y ← (byte) point1_y Replacing struct member reference (struct Point) point1.x with member unwinding reference (byte) point1_x diff --git a/src/test/ref/struct-20.log b/src/test/ref/struct-20.log index 46eb9a0de..1f6880d3c 100644 --- a/src/test/ref/struct-20.log +++ b/src/test/ref/struct-20.log @@ -2,8 +2,8 @@ Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(cons Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4 Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -Adding struct value list initializer *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← (struct Point) main::p1 -Adding struct value list initializer *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (struct Point) main::p2 +Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← (struct Point) main::p1 +Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (struct Point) main::p2 Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) diff --git a/src/test/ref/struct-23.log b/src/test/ref/struct-23.log index 2304bbd73..d1f52dc8d 100644 --- a/src/test/ref/struct-23.log +++ b/src/test/ref/struct-23.log @@ -16,8 +16,8 @@ Adding struct value member variable copy *((byte*)&(struct Point) main::point1+( Converted procedure call LValue to member unwinding { (byte~) main::$1_x, (byte~) main::$1_y } ← call getPoint (number) 4 (number) 5 Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -Adding struct value list initializer (byte) getPoint::p_x ← (byte) getPoint::x -Adding struct value list initializer (byte) getPoint::p_y ← (byte) getPoint::y +Adding struct value member variable copy (byte) getPoint::p_x ← (byte) getPoint::x +Adding struct value member variable copy (byte) getPoint::p_y ← (byte) getPoint::y Adding struct value member variable copy (byte) getPoint::return_x ← (byte) getPoint::p_x Adding struct value member variable copy (byte) getPoint::return_y ← (byte) getPoint::p_y Adding struct value member variable copy (byte) getPoint::return_x ← (byte) getPoint::return_x diff --git a/src/test/ref/struct-24.log b/src/test/ref/struct-24.log index d3d0e6f38..5c95309bc 100644 --- a/src/test/ref/struct-24.log +++ b/src/test/ref/struct-24.log @@ -1,8 +1,8 @@ Fixing struct type size struct Point to 3 Fixing struct type SIZE_OF struct Point to 3 Fixing struct type SIZE_OF struct Point to 3 -Adding struct value member variable default initializer *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 -Adding struct value member variable default initializer *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS diff --git a/src/test/ref/struct-26.asm b/src/test/ref/struct-26.asm index 885853681..f59ffdfe0 100644 --- a/src/test/ref/struct-26.asm +++ b/src/test/ref/struct-26.asm @@ -22,11 +22,11 @@ main: { sta point1+OFFSET_STRUCT_POINT_INITIALS+1 lda.z point1 sta.z point2 - ldx #2 + ldy #2 !: - lda point1+OFFSET_STRUCT_POINT_INITIALS-1,x - sta point2+OFFSET_STRUCT_POINT_INITIALS-1,x - dex + lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y + sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y + dey bne !- lda.z point2 sta SCREEN diff --git a/src/test/ref/struct-26.log b/src/test/ref/struct-26.log index 284d3c0ea..0f28d5d67 100644 --- a/src/test/ref/struct-26.log +++ b/src/test/ref/struct-26.log @@ -2,8 +2,8 @@ Fixing struct type size struct Point to 3 Fixing struct type size struct Point to 3 Fixing struct type SIZE_OF struct Point to 3 Fixing struct type SIZE_OF struct Point to 3 -Adding struct value member variable default initializer *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 -Adding struct value member variable default initializer *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) @@ -216,12 +216,12 @@ main: { // [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 lda.z point1 sta.z point2 - // [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy__vbuc3 - ldx #2 + // [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #2 !: - lda point1+OFFSET_STRUCT_POINT_INITIALS-1,x - sta point2+OFFSET_STRUCT_POINT_INITIALS-1,x - dex + lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y + sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y + dey bne !- // [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2 lda.z point2 @@ -247,7 +247,7 @@ Statement [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 Statement [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a Statement [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a Statement [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a -Statement [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a reg byte x +Statement [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a reg byte y Statement [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a Statement [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a @@ -313,12 +313,12 @@ main: { // [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 lda.z point1 sta.z point2 - // [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy__vbuc3 - ldx #2 + // [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #2 !: - lda point1+OFFSET_STRUCT_POINT_INITIALS-1,x - sta point2+OFFSET_STRUCT_POINT_INITIALS-1,x - dex + lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y + sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y + dey bne !- // [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2 lda.z point2 @@ -423,12 +423,12 @@ main: { // [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 lda.z point1 sta.z point2 - // [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy__vbuc3 - ldx #2 + // [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #2 !: - lda point1+OFFSET_STRUCT_POINT_INITIALS-1,x - sta point2+OFFSET_STRUCT_POINT_INITIALS-1,x - dex + lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y + sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y + dey bne !- // SCREEN[0] = point2.x // [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2 diff --git a/src/test/ref/struct-27.asm b/src/test/ref/struct-27.asm new file mode 100644 index 000000000..309d97383 --- /dev/null +++ b/src/test/ref/struct-27.asm @@ -0,0 +1,26 @@ +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 +main: { + .label point1 = 2 + lda #2 + sta.z point1 + ldy #3 + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + lda.z point1 + sta SCREEN + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + rts +} + __0: .text "jg" + .byte 0 diff --git a/src/test/ref/struct-27.cfg b/src/test/ref/struct-27.cfg new file mode 100644 index 000000000..b2aeed75c --- /dev/null +++ b/src/test/ref/struct-27.cfg @@ -0,0 +1,21 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 + [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) + [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) + [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) + [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) + to:main::@return +main::@return: scope:[main] from main + [9] return + to:@return diff --git a/src/test/ref/struct-27.log b/src/test/ref/struct-27.log new file mode 100644 index 000000000..232a994d5 --- /dev/null +++ b/src/test/ref/struct-27.log @@ -0,0 +1,346 @@ +Fixing struct type size struct Point to 4 +Fixing struct type SIZE_OF struct Point to 4 +Fixing struct type SIZE_OF struct Point to 4 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) +Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) +Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS +Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS +Adding versioned struct unwinding for (struct Point) main::point1 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 + *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) + (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS} + *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) + *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) + *((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1) + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(const byte*) $0[(number) 3] = (string) "jg" +(label) @1 +(label) @2 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_INITIALS = (byte) 1 +(const byte) OFFSET_STRUCT_POINT_X = (byte) 0 +(const byte*) Point::initials[(number) 3] = { fill( 3, 0) } +(byte) Point::x +(const byte*) SCREEN = (byte*)(number) $400 +(void()) main() +(label) main::@return +(struct Point) main::point1 loadstore + +Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) +Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) +Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (unumber)(number) 0) +Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1) +Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (unumber)(number) 1) +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Simplifying constant integer cast 1 +Simplifying constant integer cast 2 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 2 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS} +Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 +Simplifying expression containing zero (byte*)&main::point1 in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1) +Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X +Successful SSA optimization PassNEliminateUnusedVars +Consolidated array index constant in *(SCREEN+1) +Consolidated array index constant in *((byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS+1) +Consolidated array index constant in *(SCREEN+2) +Successful SSA optimization Pass2ConstantAdditionElimination +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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() + +(void()) main() +main: scope:[main] from @1 + [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 + [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) + [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) + [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) + [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) + to:main::@return +main::@return: scope:[main] from main + [9] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) Point::x +(void()) main() +(struct Point) main::point1 loadstore + +Initial phi equivalence classes +Added variable main::point1 to live range equivalence class [ main::point1 ] +Complete equivalence classes +[ main::point1 ] +Allocated zp[4]:2 [ main::point1 ] + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + .label point1 = 2 + // [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2 + lda #2 + sta.z point1 + // [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #3 + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + // [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 + lda.z point1 + sta SCREEN + // [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + // [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + jmp __breturn + // main::@return + __breturn: + // [9] return + rts +} + // File Data + __0: .text "jg" + .byte 0 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a +Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a +Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a +Statement [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a +Potential registers zp[4]:2 [ main::point1 ] : zp[4]:2 , + +REGISTER UPLIFT SCOPES +Uplift Scope [Point] +Uplift Scope [main] 0: zp[4]:2 [ main::point1 ] +Uplift Scope [] + +Uplifting [Point] best 65 combination +Uplifting [main] best 65 combination zp[4]:2 [ main::point1 ] +Uplifting [] best 65 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + .label point1 = 2 + // [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2 + lda #2 + sta.z point1 + // [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #3 + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + // [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 + lda.z point1 + sta SCREEN + // [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + // [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + jmp __breturn + // main::@return + __breturn: + // [9] return + rts +} + // File Data + __0: .text "jg" + .byte 0 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing label __bbegin with __b1 +Removing instruction __bbegin: +Removing instruction __b1_from___bbegin: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __bend: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction __b1: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(const byte*) $0[(number) 3] = (string) "jg" +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_INITIALS = (byte) 1 +(const byte*) Point::initials[(number) 3] = { fill( 3, 0) } +(byte) Point::x +(const byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +(struct Point) main::point1 loadstore zp[4]:2 + +zp[4]:2 [ main::point1 ] + + +FINAL ASSEMBLER +Score: 50 + + // File Comments +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 + // @begin + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + .label point1 = 2 + // point1 = { 2, "jg" } + // [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2 + lda #2 + sta.z point1 + // [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #3 + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + // SCREEN[0] = point1.x + // [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 + lda.z point1 + sta SCREEN + // SCREEN[1] = point1.initials[0] + // [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + // SCREEN[2] = point1.initials[1] + // [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + // main::@return + // } + // [9] return + rts +} + // File Data + __0: .text "jg" + .byte 0 + diff --git a/src/test/ref/struct-27.sym b/src/test/ref/struct-27.sym new file mode 100644 index 000000000..1b5fe72b3 --- /dev/null +++ b/src/test/ref/struct-27.sym @@ -0,0 +1,13 @@ +(const byte*) $0[(number) 3] = (string) "jg" +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_INITIALS = (byte) 1 +(const byte*) Point::initials[(number) 3] = { fill( 3, 0) } +(byte) Point::x +(const byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +(struct Point) main::point1 loadstore zp[4]:2 + +zp[4]:2 [ main::point1 ] diff --git a/src/test/ref/struct-28.asm b/src/test/ref/struct-28.asm new file mode 100644 index 000000000..e7d7795e6 --- /dev/null +++ b/src/test/ref/struct-28.asm @@ -0,0 +1,25 @@ +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 +main: { + .label point1 = 2 + lda #2 + sta.z point1 + tay + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + lda.z point1 + sta SCREEN + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + rts +} + __0: .byte 'j', 'g' diff --git a/src/test/ref/struct-28.cfg b/src/test/ref/struct-28.cfg new file mode 100644 index 000000000..044dd321d --- /dev/null +++ b/src/test/ref/struct-28.cfg @@ -0,0 +1,21 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 + [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) + [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) + [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) + [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) + to:main::@return +main::@return: scope:[main] from main + [9] return + to:@return diff --git a/src/test/ref/struct-28.log b/src/test/ref/struct-28.log new file mode 100644 index 000000000..bc175845f --- /dev/null +++ b/src/test/ref/struct-28.log @@ -0,0 +1,344 @@ +Fixing struct type size struct Point to 3 +Fixing struct type SIZE_OF struct Point to 3 +Fixing struct type SIZE_OF struct Point to 3 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 +Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) +Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) +Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS +Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS +Adding versioned struct unwinding for (struct Point) main::point1 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 + *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) + (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS} + *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) + *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) + *((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1) + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' } +(label) @1 +(label) @2 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_INITIALS = (byte) 1 +(const byte) OFFSET_STRUCT_POINT_X = (byte) 0 +(const byte*) Point::initials[(number) 2] = { fill( 2, 0) } +(byte) Point::x +(const byte*) SCREEN = (byte*)(number) $400 +(void()) main() +(label) main::@return +(struct Point) main::point1 loadstore + +Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) +Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) +Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (unumber)(number) 0) +Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1) +Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (unumber)(number) 1) +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Simplifying constant integer cast 1 +Simplifying constant integer cast 2 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 2 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS} +Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2 +Simplifying expression containing zero (byte*)&main::point1 in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1) +Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X +Successful SSA optimization PassNEliminateUnusedVars +Consolidated array index constant in *(SCREEN+1) +Consolidated array index constant in *((byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS+1) +Consolidated array index constant in *(SCREEN+2) +Successful SSA optimization Pass2ConstantAdditionElimination +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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() + +(void()) main() +main: scope:[main] from @1 + [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 + [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) + [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) + [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) + [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) + to:main::@return +main::@return: scope:[main] from main + [9] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) Point::x +(void()) main() +(struct Point) main::point1 loadstore + +Initial phi equivalence classes +Added variable main::point1 to live range equivalence class [ main::point1 ] +Complete equivalence classes +[ main::point1 ] +Allocated zp[3]:2 [ main::point1 ] + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + .label point1 = 2 + // [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2 + lda #2 + sta.z point1 + // [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #2 + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + // [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 + lda.z point1 + sta SCREEN + // [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + // [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + jmp __breturn + // main::@return + __breturn: + // [9] return + rts +} + // File Data + __0: .byte 'j', 'g' + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a +Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a +Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a +Statement [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a +Potential registers zp[3]:2 [ main::point1 ] : zp[3]:2 , + +REGISTER UPLIFT SCOPES +Uplift Scope [Point] +Uplift Scope [main] 0: zp[3]:2 [ main::point1 ] +Uplift Scope [] + +Uplifting [Point] best 65 combination +Uplifting [main] best 65 combination zp[3]:2 [ main::point1 ] +Uplifting [] best 65 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + .label point1 = 2 + // [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2 + lda #2 + sta.z point1 + // [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #2 + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + // [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 + lda.z point1 + sta SCREEN + // [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + // [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + jmp __breturn + // main::@return + __breturn: + // [9] return + rts +} + // File Data + __0: .byte 'j', 'g' + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing instruction ldy #2 with TAY +Replacing label __bbegin with __b1 +Removing instruction __bbegin: +Removing instruction __b1_from___bbegin: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __bend: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction __b1: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' } +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_INITIALS = (byte) 1 +(const byte*) Point::initials[(number) 2] = { fill( 2, 0) } +(byte) Point::x +(const byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +(struct Point) main::point1 loadstore zp[3]:2 + +zp[3]:2 [ main::point1 ] + + +FINAL ASSEMBLER +Score: 50 + + // File Comments +// Minimal struct with C-Standard behavior - member is array, copy assignment (not supported yet) + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_INITIALS = 1 + // @begin + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + .label point1 = 2 + // point1 = { 2, { 'j', 'g' } } + // [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2 + lda #2 + sta.z point1 + // [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + tay + !: + lda __0-1,y + sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y + dey + bne !- + // SCREEN[0] = point1.x + // [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2 + lda.z point1 + sta SCREEN + // SCREEN[1] = point1.initials[0] + // [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS + sta SCREEN+1 + // SCREEN[2] = point1.initials[1] + // [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 + lda point1+OFFSET_STRUCT_POINT_INITIALS+1 + sta SCREEN+2 + // main::@return + // } + // [9] return + rts +} + // File Data + __0: .byte 'j', 'g' + diff --git a/src/test/ref/struct-28.sym b/src/test/ref/struct-28.sym new file mode 100644 index 000000000..b9c19c2fe --- /dev/null +++ b/src/test/ref/struct-28.sym @@ -0,0 +1,13 @@ +(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' } +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_INITIALS = (byte) 1 +(const byte*) Point::initials[(number) 2] = { fill( 2, 0) } +(byte) Point::x +(const byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +(struct Point) main::point1 loadstore zp[3]:2 + +zp[3]:2 [ main::point1 ] diff --git a/src/test/ref/struct-3.log b/src/test/ref/struct-3.log index b580ecfe2..347881def 100644 --- a/src/test/ref/struct-3.log +++ b/src/test/ref/struct-3.log @@ -5,8 +5,8 @@ Created struct value member variable (byte) print::p_x Created struct value member variable (byte) print::p_y Converted struct value to member variables (struct Point) print::p Converted procedure struct value parameter to member unwinding (void()) print((byte) print::p_x , (byte) print::p_y) -Adding struct value member variable default initializer (byte) main::p1_x ← (byte) 0 -Adding struct value member variable default initializer (byte) main::p1_y ← (byte) 0 +Adding struct value member variable copy (byte) main::p1_x ← (byte) 0 +Adding struct value member variable copy (byte) main::p1_y ← (byte) 0 Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print (byte) main::p1_x (byte) main::p1_y Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print (byte) main::p1_x (byte) main::p1_y Replacing struct member reference (struct Point) main::p1.x with member unwinding reference (byte) main::p1_x diff --git a/src/test/ref/struct-4.log b/src/test/ref/struct-4.log index 3acdfcd7d..2c0ad2130 100644 --- a/src/test/ref/struct-4.log +++ b/src/test/ref/struct-4.log @@ -1,8 +1,8 @@ Created struct value member variable (byte) main::p_x Created struct value member variable (byte) main::p_y Converted struct value to member variables (struct Point) main::p -Adding struct value list initializer (byte) main::p_x ← (byte) main::x -Adding struct value list initializer (byte) main::p_y ← (number~) main::$0 +Adding struct value member variable copy (byte) main::p_x ← (byte) main::x +Adding struct value member variable copy (byte) main::p_y ← (number~) main::$0 Replacing struct member reference (struct Point) main::p.x with member unwinding reference (byte) main::p_x Replacing struct member reference (struct Point) main::p.y with member unwinding reference (byte) main::p_y Identified constant variable (byte) main::x diff --git a/src/test/ref/struct-5.log b/src/test/ref/struct-5.log index 26deb56ff..d85f726e7 100644 --- a/src/test/ref/struct-5.log +++ b/src/test/ref/struct-5.log @@ -10,8 +10,8 @@ Converted struct value to member variables (struct Point) point::return Created struct value member variable (byte) point::p_x Created struct value member variable (byte) point::p_y Converted struct value to member variables (struct Point) point::p -Adding struct value member variable default initializer (byte) main::q_x ← (byte) 0 -Adding struct value member variable default initializer (byte) main::q_y ← (byte) 0 +Adding struct value member variable copy (byte) main::q_x ← (byte) 0 +Adding struct value member variable copy (byte) main::q_y ← (byte) 0 Converted procedure call LValue to member unwinding { (byte~) main::$0_x, (byte~) main::$0_y } ← call point Adding struct value member variable copy (byte) main::q_x ← (byte~) main::$0_x Adding struct value member variable copy (byte) main::q_y ← (byte~) main::$0_y diff --git a/src/test/ref/struct-6.log b/src/test/ref/struct-6.log index 5407a13ec..a654d1bba 100644 --- a/src/test/ref/struct-6.log +++ b/src/test/ref/struct-6.log @@ -9,8 +9,8 @@ Created struct value member variable (byte) main::c_center_y Converted struct value to member variables (struct Point) main::c_center Adding struct value member variable copy (byte) main::p_x ← (byte) $a Adding struct value member variable copy (byte) main::p_y ← (byte) $a -Adding struct value list initializer (struct Point) main::c_center ← (struct Point) main::p -Adding struct value list initializer (byte) main::c_radius ← (byte) 5 +Adding struct value member variable copy (struct Point) main::c_center ← (struct Point) main::p +Adding struct value member variable copy (byte) main::c_radius ← (byte) 5 Replacing struct member reference (struct Circle) main::c.center with member unwinding reference (struct Point) main::c_center Replacing struct member reference (struct Circle) main::c.center with member unwinding reference (struct Point) main::c_center Replacing struct member reference (struct Circle) main::c.radius with member unwinding reference (byte) main::c_radius diff --git a/src/test/ref/struct-8.log b/src/test/ref/struct-8.log index fa1414d1a..271eb6641 100644 --- a/src/test/ref/struct-8.log +++ b/src/test/ref/struct-8.log @@ -12,8 +12,8 @@ Created struct value member variable (byte) main::c_center_y Converted struct value to member variables (struct Point) main::c_center Adding struct value member variable copy (byte) main::p_x ← (byte) $a Adding struct value member variable copy (byte) main::p_y ← (byte) $a -Adding struct value list initializer (struct Point) main::c_center ← (struct Point) main::p -Adding struct value list initializer (byte) main::c_radius ← (byte) 5 +Adding struct value member variable copy (struct Point) main::c_center ← (struct Point) main::p +Adding struct value member variable copy (byte) main::c_radius ← (byte) 5 Replacing struct member reference (struct Circle) main::c.center with member unwinding reference (struct Point) main::c_center Replacing struct member reference (struct Point) main::point.x with member unwinding reference (byte) main::point_x Replacing struct member reference (struct Point) main::point.y with member unwinding reference (byte) main::point_y diff --git a/src/test/ref/struct-9.log b/src/test/ref/struct-9.log index 8d9af09c4..fe4c53227 100644 --- a/src/test/ref/struct-9.log +++ b/src/test/ref/struct-9.log @@ -9,15 +9,15 @@ Created struct value member variable (byte) main::c_center_y Converted struct value to member variables (struct Point) main::c_center Adding struct value member variable copy (byte) main::p_x ← (byte) $a Adding struct value member variable copy (byte) main::p_y ← (byte) $a -Adding struct value member variable default initializer (struct Point) main::c_center ← {} -Adding struct value member variable default initializer (byte) main::c_radius ← (byte) 0 +Adding struct value member variable copy (struct Point) main::c_center ← { x: (byte) 0, y: (byte) 0 } +Adding struct value member variable copy (byte) main::c_radius ← (byte) 0 Replacing struct member reference (struct Circle) main::c.center with member unwinding reference (struct Point) main::c_center Replacing struct member reference (struct Circle) main::c.radius with member unwinding reference (byte) main::c_radius Replacing struct member reference (struct Circle) main::c.center with member unwinding reference (struct Point) main::c_center Replacing struct member reference (struct Circle) main::c.center with member unwinding reference (struct Point) main::c_center Replacing struct member reference (struct Circle) main::c.radius with member unwinding reference (byte) main::c_radius -Adding struct value member variable default initializer (byte) main::c_center_x ← (byte) 0 -Adding struct value member variable default initializer (byte) main::c_center_y ← (byte) 0 +Adding struct value member variable copy (byte) main::c_center_x ← (byte) 0 +Adding struct value member variable copy (byte) main::c_center_y ← (byte) 0 Adding struct value member variable copy (byte) main::c_center_x ← (byte) main::p_x Adding struct value member variable copy (byte) main::c_center_y ← (byte) main::p_y Replacing struct member reference (struct Point) main::c_center.x with member unwinding reference (byte) main::c_center_x diff --git a/src/test/ref/struct-ptr-10.log b/src/test/ref/struct-ptr-10.log index b1849d7c9..83621df3c 100644 --- a/src/test/ref/struct-ptr-10.log +++ b/src/test/ref/struct-ptr-10.log @@ -1,8 +1,9 @@ Fixing pointer array-indexing *((const struct Point*) points + (word) main::i) Fixing pointer array-indexing *((const struct Point*) points + (word) main::i1) Fixing pointer array-indexing *((const struct Point*) main::SCREEN + (word) main::i1) -Adding struct value list initializer *((byte*~) main::$5 + (word~) main::$3) ← (number) 2 -Adding struct value list initializer *((byte*~) main::$6 + (word~) main::$3) ← (byte~) main::$0 +Constantified RValue *((const struct Point*) points + (word~) main::$3) ← (struct Point){ (byte) 2, (byte~) main::$0 } +Adding struct value member variable copy *((byte*~) main::$5 + (word~) main::$3) ← (byte) 2 +Adding struct value member variable copy *((byte*~) main::$6 + (word~) main::$3) ← (byte~) main::$0 Adding struct value member variable copy *((byte*~) main::$7 + (word~) main::$4) ← *((byte*~) main::$8 + (word~) main::$4) Adding struct value member variable copy *((byte*~) main::$9 + (word~) main::$4) ← *((byte*~) main::$10 + (word~) main::$4) Culled Empty Block (label) main::@4 @@ -20,7 +21,7 @@ main::@1: scope:[main] from main main::@1 (byte~) main::$0 ← ((byte)) (word) main::i#2 (word~) main::$3 ← (word) main::i#2 * (const byte) SIZEOF_STRUCT_POINT (byte*~) main::$5 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_X - *((byte*~) main::$5 + (word~) main::$3) ← (number) 2 + *((byte*~) main::$5 + (word~) main::$3) ← (byte) 2 (byte*~) main::$6 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_Y *((byte*~) main::$6 + (word~) main::$3) ← (byte~) main::$0 (word) main::i#1 ← (word) main::i#2 + rangenext(0,$1f3) @@ -90,16 +91,10 @@ SYMBOL TABLE SSA (word) main::i1#2 (const struct Point*) points[(number) $1f4] = { fill( $1f4, 0) } -Adding number conversion cast (unumber) 2 in *((byte*~) main::$5 + (word~) main::$3) ← (number) 2 -Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (byte~) main::$0 ← (byte)(word) main::i#2 -Inlining cast *((byte*~) main::$5 + (word~) main::$3) ← (unumber)(number) 2 Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (struct Point*) 1024 -Simplifying constant integer cast 2 Successful SSA optimization PassNCastSimplification -Finalized unsigned number type (byte) 2 -Successful SSA optimization PassNFinalizeNumberTypeConversions Simple Condition (bool~) main::$1 [10] if((word) main::i#1!=rangelast(0,$1f3)) goto main::@1 Simple Condition (bool~) main::$2 [22] if((word) main::i1#1!=rangelast(0,$1f3)) goto main::@3 Successful SSA optimization Pass2ConditionalJumpSimplification diff --git a/src/test/ref/struct-ptr-11.log b/src/test/ref/struct-ptr-11.log index 9bf053f34..732619ee4 100644 --- a/src/test/ref/struct-ptr-11.log +++ b/src/test/ref/struct-ptr-11.log @@ -1,9 +1,10 @@ Fixing pointer array-indexing *((const struct Point*) points + (byte) main::i) Fixing pointer array-indexing *((const struct Point*) points + (byte) main::i1) Fixing pointer array-indexing *((const struct Point*) main::SCREEN + (byte) main::i1) -Adding struct value list initializer *((signed byte*~) main::$8 + (byte~) main::$6) ← (signed byte~) main::$0 -Adding struct value list initializer *((signed byte*~) main::$9 + (byte~) main::$6) ← (signed byte~) main::$2 -Adding struct value list initializer *((signed byte*~) main::$10 + (byte~) main::$6) ← (signed byte~) main::$3 +Constantified RValue *((const struct Point*) points + (byte~) main::$6) ← (struct Point){ (signed byte~) main::$0, (signed byte~) main::$2, (signed byte~) main::$3 } +Adding struct value member variable copy *((signed byte*~) main::$8 + (byte~) main::$6) ← (signed byte~) main::$0 +Adding struct value member variable copy *((signed byte*~) main::$9 + (byte~) main::$6) ← (signed byte~) main::$2 +Adding struct value member variable copy *((signed byte*~) main::$10 + (byte~) main::$6) ← (signed byte~) main::$3 Adding struct value member variable copy *((signed byte*~) main::$11 + (byte~) main::$7) ← *((signed byte*~) main::$12 + (byte~) main::$7) Adding struct value member variable copy *((signed byte*~) main::$13 + (byte~) main::$7) ← *((signed byte*~) main::$14 + (byte~) main::$7) Adding struct value member variable copy *((signed byte*~) main::$15 + (byte~) main::$7) ← *((signed byte*~) main::$16 + (byte~) main::$7) diff --git a/src/test/ref/struct-ptr-17.log b/src/test/ref/struct-ptr-17.log index e40eda3e6..4d2bbf712 100644 --- a/src/test/ref/struct-ptr-17.log +++ b/src/test/ref/struct-ptr-17.log @@ -17,8 +17,8 @@ Adding struct value member variable copy *((byte*~) main::$5) ← (byte~) main:: Converted procedure call LValue to member unwinding { (byte~) main::$1_x, (byte~) main::$1_y } ← call get (byte) main::i Adding struct value member variable copy *((byte*~) main::$6 + (byte~) main::$3) ← (byte~) main::$1_x Adding struct value member variable copy *((byte*~) main::$7 + (byte~) main::$3) ← (byte~) main::$1_y -Adding struct value list initializer (byte) get::p_x ← (byte) get::i -Adding struct value list initializer (byte) get::p_y ← (byte) 7 +Adding struct value member variable copy (byte) get::p_x ← (byte) get::i +Adding struct value member variable copy (byte) get::p_y ← (byte) 7 Adding struct value member variable copy (byte) get::return_x ← (byte) get::p_x Adding struct value member variable copy (byte) get::return_y ← (byte) get::p_y Adding struct value member variable copy (byte) get::return_x ← (byte) get::return_x diff --git a/src/test/ref/struct-ptr-18.log b/src/test/ref/struct-ptr-18.log index 70318cb42..1a885f31c 100644 --- a/src/test/ref/struct-ptr-18.log +++ b/src/test/ref/struct-ptr-18.log @@ -1,14 +1,16 @@ Fixing pointer array-indexing *((const struct Point*) points + (number) 0) Fixing pointer array-indexing *((const struct Point*) points + (number) 1) Fixing pointer array-indexing *((const struct Point*) points + (byte) main::i) +Constantified RValue *((const struct Point*) points + (number~) main::$2) ← { x: (byte) 1, y: (byte) 2 } +Constantified RValue *((const struct Point*) points + (number~) main::$3) ← { x: (byte) 3, y: (byte) 4 } Created struct value member variable (byte) print::p_x Created struct value member variable (byte) print::p_y Converted struct value to member variables (struct Point) print::p Converted procedure struct value parameter to member unwinding (void()) print((byte) print::p_x , (byte) print::p_y) -Adding struct value list initializer *((byte*~) main::$5 + (number~) main::$2) ← (number) 1 -Adding struct value list initializer *((byte*~) main::$6 + (number~) main::$2) ← (number) 2 -Adding struct value list initializer *((byte*~) main::$7 + (number~) main::$3) ← (number) 3 -Adding struct value list initializer *((byte*~) main::$8 + (number~) main::$3) ← (number) 4 +Adding struct value member variable copy *((byte*~) main::$5 + (number~) main::$2) ← (byte) 1 +Adding struct value member variable copy *((byte*~) main::$6 + (number~) main::$2) ← (byte) 2 +Adding struct value member variable copy *((byte*~) main::$7 + (number~) main::$3) ← (byte) 3 +Adding struct value member variable copy *((byte*~) main::$8 + (number~) main::$3) ← (byte) 4 Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print *((byte*~) main::$9 + (byte~) main::$4) *((byte*~) main::$10 + (byte~) main::$4) Replacing struct member reference (struct Point) print::p.x with member unwinding reference (byte) print::p_x Replacing struct member reference (struct Point) print::p.y with member unwinding reference (byte) print::p_y @@ -25,14 +27,14 @@ main: scope:[main] from @2 (byte) idx#14 ← phi( @2/(byte) idx#13 ) (number~) main::$2 ← (number) 0 * (const byte) SIZEOF_STRUCT_POINT (byte*~) main::$5 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_X - *((byte*~) main::$5 + (number~) main::$2) ← (number) 1 + *((byte*~) main::$5 + (number~) main::$2) ← (byte) 1 (byte*~) main::$6 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_Y - *((byte*~) main::$6 + (number~) main::$2) ← (number) 2 + *((byte*~) main::$6 + (number~) main::$2) ← (byte) 2 (number~) main::$3 ← (number) 1 * (const byte) SIZEOF_STRUCT_POINT (byte*~) main::$7 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_X - *((byte*~) main::$7 + (number~) main::$3) ← (number) 3 + *((byte*~) main::$7 + (number~) main::$3) ← (byte) 3 (byte*~) main::$8 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_Y - *((byte*~) main::$8 + (number~) main::$3) ← (number) 4 + *((byte*~) main::$8 + (number~) main::$3) ← (byte) 4 (byte) main::i#0 ← (byte) 0 to:main::@1 main::@1: scope:[main] from main main::@3 @@ -143,32 +145,15 @@ SYMBOL TABLE SSA Adding number conversion cast (unumber) 0 in (number~) main::$2 ← (number) 0 * (const byte) SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$2 in (number~) main::$2 ← (unumber)(number) 0 * (const byte) SIZEOF_STRUCT_POINT -Adding number conversion cast (unumber) 1 in *((byte*~) main::$5 + (unumber~) main::$2) ← (number) 1 -Adding number conversion cast (unumber) 2 in *((byte*~) main::$6 + (unumber~) main::$2) ← (number) 2 Adding number conversion cast (unumber) 1 in (number~) main::$3 ← (number) 1 * (const byte) SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$3 in (number~) main::$3 ← (unumber)(number) 1 * (const byte) SIZEOF_STRUCT_POINT -Adding number conversion cast (unumber) 3 in *((byte*~) main::$7 + (unumber~) main::$3) ← (number) 3 -Adding number conversion cast (unumber) 4 in *((byte*~) main::$8 + (unumber~) main::$3) ← (number) 4 Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast *((byte*~) main::$5 + (unumber~) main::$2) ← (unumber)(number) 1 -Inlining cast *((byte*~) main::$6 + (unumber~) main::$2) ← (unumber)(number) 2 -Inlining cast *((byte*~) main::$7 + (unumber~) main::$3) ← (unumber)(number) 3 -Inlining cast *((byte*~) main::$8 + (unumber~) main::$3) ← (unumber)(number) 4 -Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 0 Simplifying constant integer cast 1 -Simplifying constant integer cast 2 -Simplifying constant integer cast 1 -Simplifying constant integer cast 3 -Simplifying constant integer cast 4 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 1 -Finalized unsigned number type (byte) 2 -Finalized unsigned number type (byte) 1 -Finalized unsigned number type (byte) 3 -Finalized unsigned number type (byte) 4 Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to byte in (unumber~) main::$2 ← (byte) 0 * (const byte) SIZEOF_STRUCT_POINT Inferred type updated to byte in (unumber~) main::$3 ← (byte) 1 * (const byte) SIZEOF_STRUCT_POINT diff --git a/src/test/ref/struct-ptr-34.asm b/src/test/ref/struct-ptr-34.asm index 874781547..decf1e950 100644 --- a/src/test/ref/struct-ptr-34.asm +++ b/src/test/ref/struct-ptr-34.asm @@ -3,16 +3,30 @@ :BasicUpstart(main) .pc = $80d "Program" .label SCREEN = $400 + .label idx = 2 main: { .const jesper_id = 4 .const henriette_id = 7 + ldy #$10 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- lda #jesper_name sta.z print_person.person_name+1 - ldy #0 + lda #0 + sta.z idx ldx #jesper_id jsr print_person + ldy #$10 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- lda #henriette_name @@ -20,20 +34,16 @@ main: { ldx #henriette_id jsr print_person rts - jesper_name: .text "jesper" - .byte 0 - .fill 9, 0 - henriette_name: .text "henriette" - .byte 0 - .fill 6, 0 + jesper_name: .fill $10, 0 + henriette_name: .fill $10, 0 } -// print_person(byte register(X) person_id, byte* zeropage(2) person_name) +// print_person(byte register(X) person_id, byte* zp(3) person_name) print_person: { - .label person_name = 2 + .label person_name = 3 lda DIGIT,x + ldy.z idx sta SCREEN,y - tya - tax + ldx.z idx inx lda #' ' sta SCREEN,x @@ -45,9 +55,8 @@ print_person: { bne __b2 lda #' ' sta SCREEN,x - txa - tay - iny + inx + stx.z idx rts __b2: lda (person_name),y @@ -58,3 +67,9 @@ print_person: { } DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill 9, 0 + __1: .text "henriette" + .byte 0 + .fill 6, 0 diff --git a/src/test/ref/struct-ptr-34.cfg b/src/test/ref/struct-ptr-34.cfg index e56f8bec1..afbe9c71c 100644 --- a/src/test/ref/struct-ptr-34.cfg +++ b/src/test/ref/struct-ptr-34.cfg @@ -10,18 +10,18 @@ (void()) main() main: scope:[main] from @1 - [4] phi() + [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) [5] call print_person to:main::@1 main::@1: scope:[main] from main - [6] phi() + [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) [7] call print_person to:main::@return main::@return: scope:[main] from main::@1 [8] return to:@return -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 [9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name main::@1/(const byte*) main::henriette_name ) [9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) diff --git a/src/test/ref/struct-ptr-34.log b/src/test/ref/struct-ptr-34.log index a58697962..f49360c8a 100644 --- a/src/test/ref/struct-ptr-34.log +++ b/src/test/ref/struct-ptr-34.log @@ -1,6 +1,8 @@ Fixing struct type size struct Person to 17 Fixing struct type size struct Person to 17 Fixing struct type size struct Person to 17 +Fixing struct type SIZE_OF struct Person to 17 +Fixing struct type SIZE_OF struct Person to 17 Created struct value member variable (byte) main::jesper_id Created struct value member variable (const byte*) main::jesper_name Converted struct value to member variables (struct Person) main::jesper @@ -8,23 +10,21 @@ Created struct value member variable (byte) main::henriette_id Created struct value member variable (const byte*) main::henriette_name Converted struct value to member variables (struct Person) main::henriette Created struct value member variable (byte) print_person::person_id -Created struct value member variable (const byte*) print_person::person_name +Created struct value member variable (byte*) print_person::person_name Converted struct value to member variables (struct Person) print_person::person -Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) -Adding struct value list initializer (byte) main::jesper_id ← (number) 4 -Adding struct value list initializer (const byte*) main::jesper_name ← (string) "jesper" +Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) +Adding struct value member variable copy (byte) main::jesper_id ← (byte) 4 +Adding struct value member variable copy *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (const byte*) main::jesper_name -Adding struct value list initializer (byte) main::henriette_id ← (number) 7 -Adding struct value list initializer (const byte*) main::henriette_name ← (string) "henriette" +Adding struct value member variable copy (byte) main::henriette_id ← (byte) 7 +Adding struct value member variable copy *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (const byte*) main::henriette_name Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id -Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name -Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name -Warning! Adding boolean cast to non-boolean condition *((const byte*) print_person::person_name + (byte) print_person::i) +Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name +Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name +Warning! Adding boolean cast to non-boolean condition *((byte*) print_person::person_name + (byte) print_person::i) Identified constant variable (byte) main::jesper_id -Identified constant variable (const byte*) main::jesper_name Identified constant variable (byte) main::henriette_id -Identified constant variable (const byte*) main::henriette_name Culled Empty Block (label) print_person::@4 Culled Empty Block (label) print_person::@5 Culled Empty Block (label) print_person::@6 @@ -36,6 +36,7 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 (byte) idx#18 ← phi( @2/(byte) idx#20 ) + *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) (byte) print_person::person_id#0 ← (const byte) main::jesper_id (byte*) print_person::person_name#0 ← (const byte*) main::jesper_name call print_person @@ -43,6 +44,7 @@ main: scope:[main] from @2 main::@1: scope:[main] from main (byte) idx#10 ← phi( main/(byte) idx#8 ) (byte) idx#0 ← (byte) idx#10 + *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) (byte) print_person::person_id#1 ← (const byte) main::henriette_id (byte*) print_person::person_name#1 ← (const byte*) main::henriette_name call print_person @@ -57,10 +59,10 @@ main::@return: scope:[main] from main::@2 return to:@return @1: scope:[] from @begin - (byte) idx#3 ← (number) 0 + (byte) idx#3 ← (byte) 0 to:@2 -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 (byte*) print_person::person_name#4 ← phi( main/(byte*) print_person::person_name#0 main::@1/(byte*) print_person::person_name#1 ) (byte) idx#13 ← phi( main/(byte) idx#18 main::@1/(byte) idx#0 ) @@ -69,7 +71,7 @@ print_person: scope:[print_person] from main main::@1 (byte) idx#4 ← ++ (byte) idx#13 *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' (byte) idx#5 ← ++ (byte) idx#4 - (byte) print_person::i#0 ← (number) 0 + (byte) print_person::i#0 ← (byte) 0 to:print_person::@1 print_person::@1: scope:[print_person] from print_person print_person::@2 (byte) idx#19 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 ) @@ -107,14 +109,16 @@ print_person::@return: scope:[print_person] from print_person::@3 @end: scope:[] from @3 SYMBOL TABLE SSA +(const byte*) $0[(number) $10] = (string) "jesper" +(const byte*) $1[(number) $10] = (string) "henriette" (label) @1 (label) @2 (label) @3 (label) @begin (label) @end -(const byte*) DIGIT = (string) "0123456789" +(const byte*) DIGIT[] = (string) "0123456789" (byte) Person::id -(const byte*) Person::name = { fill( $10, 0) } +(const byte*) Person::name[(number) $10] = { fill( $10, 0) } (const byte*) SCREEN = (byte*)(number) $400 (byte) idx (byte) idx#0 @@ -143,10 +147,10 @@ SYMBOL TABLE SSA (label) main::@2 (label) main::@return (const byte) main::henriette_id = (byte) 7 -(const byte*) main::henriette_name = (string) "henriette" +(const byte*) main::henriette_name[(number) $10] = { fill( $10, 0) } (const byte) main::jesper_id = (byte) 4 -(const byte*) main::jesper_name = (string) "jesper" -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(const byte*) main::jesper_name[(number) $10] = { fill( $10, 0) } +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (bool~) print_person::$0 (label) print_person::@1 (label) print_person::@2 @@ -162,28 +166,19 @@ SYMBOL TABLE SSA (byte) print_person::person_id#0 (byte) print_person::person_id#1 (byte) print_person::person_id#2 -(const byte*) print_person::person_name +(byte*) print_person::person_name (byte*) print_person::person_name#0 (byte*) print_person::person_name#1 (byte*) print_person::person_name#2 (byte*) print_person::person_name#3 (byte*) print_person::person_name#4 -Adding number conversion cast (unumber) 0 in (byte) idx#3 ← (number) 0 -Adding number conversion cast (unumber) 0 in (byte) print_person::i#0 ← (number) 0 Adding number conversion cast (unumber) 0 in (bool~) print_person::$0 ← (number) 0 != *((byte*) print_person::person_name#2 + (byte) print_person::i#2) Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast (byte) idx#3 ← (unumber)(number) 0 -Inlining cast (byte) print_person::i#0 ← (unumber)(number) 0 -Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 0 -Simplifying constant integer cast 0 -Simplifying constant integer cast 0 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (byte) idx#0 = (byte) idx#10 Alias (byte) idx#1 = (byte) idx#11 (byte) idx#12 (byte) idx#2 @@ -200,7 +195,7 @@ Identical Phi Values (byte) idx#1 (byte) idx#16 Identical Phi Values (byte*) print_person::person_name#2 (byte*) print_person::person_name#4 Identical Phi Values (byte) idx#17 (byte) idx#1 Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition (bool~) print_person::$0 [23] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 +Simple Condition (bool~) print_person::$0 [25] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte) print_person::person_id#0 = main::jesper_id Constant (const byte*) print_person::person_name#0 = main::jesper_name @@ -215,11 +210,11 @@ Inlining constant with var siblings (const byte) print_person::person_id#1 Inlining constant with var siblings (const byte*) print_person::person_name#1 Inlining constant with var siblings (const byte) print_person::i#0 Inlining constant with var siblings (const byte) idx#20 -Constant inlined print_person::person_name#1 = (const byte*) main::henriette_name Constant inlined idx#20 = (byte) 0 Constant inlined print_person::person_id#1 = (const byte) main::henriette_id Constant inlined print_person::person_id#0 = (const byte) main::jesper_id Constant inlined print_person::i#0 = (byte) 0 +Constant inlined print_person::person_name#1 = (const byte*) main::henriette_name Constant inlined print_person::person_name#0 = (const byte*) main::jesper_name Successful SSA optimization Pass2ConstantInlining Adding NOP phi() at start of @begin @@ -227,17 +222,16 @@ Adding NOP phi() at start of @1 Adding NOP phi() at start of @2 Adding NOP phi() at start of @3 Adding NOP phi() at start of @end -Adding NOP phi() at start of main Adding NOP phi() at start of main::@2 CALL GRAPH Calls in [] to main:3 -Calls in [main] to print_person:7 print_person:9 +Calls in [main] to print_person:7 print_person:10 Created 5 initial phi equivalence classes -Coalesced [8] idx#21 ← idx#16 -Coalesced [17] idx#22 ← idx#5 -Coalesced [26] print_person::i#4 ← print_person::i#1 -Coalesced [27] idx#23 ← idx#6 +Coalesced [9] idx#21 ← idx#16 +Coalesced [18] idx#22 ← idx#5 +Coalesced [27] print_person::i#4 ← print_person::i#1 +Coalesced [28] idx#23 ← idx#6 Coalesced down to 5 phi equivalence classes Culled Empty Block (label) @1 Culled Empty Block (label) @3 @@ -246,8 +240,6 @@ Renumbering block @2 to @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 -Adding NOP phi() at start of main::@1 FINAL CONTROL FLOW GRAPH @begin: scope:[] from @@ -262,18 +254,18 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] phi() + [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) [5] call print_person to:main::@1 main::@1: scope:[main] from main - [6] phi() + [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) [7] call print_person to:main::@return main::@return: scope:[main] from main::@1 [8] return to:@return -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) print_person: scope:[print_person] from main main::@1 [9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name main::@1/(const byte*) main::henriette_name ) [9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) @@ -312,14 +304,14 @@ VARIABLE REGISTER WEIGHTS (byte) idx#5 4.0 (byte) idx#6 11.0 (void()) main() -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (byte) print_person::i (byte) print_person::i#1 22.0 (byte) print_person::i#2 11.0 (struct Person) print_person::person (byte) print_person::person_id (byte) print_person::person_id#2 2.0 -(const byte*) print_person::person_name +(byte*) print_person::person_name (byte*) print_person::person_name#4 2.2 Initial phi equivalence classes @@ -364,8 +356,6 @@ __b1_from___bbegin: // @1 __b1: // [2] call main - // [4] phi from @1 to main [phi:@1->main] -main_from___b1: jsr main // [3] phi from @1 to @end [phi:@1->@end] __bend_from___b1: @@ -376,6 +366,13 @@ __bend: main: { .const jesper_id = 4 .const henriette_id = 7 + // [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$10 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- // [5] call print_person // [9] phi from main to print_person [phi:main->print_person] print_person_from_main: @@ -391,11 +388,16 @@ main: { lda #jesper_id sta.z print_person.person_id jsr print_person - // [6] phi from main to main::@1 [phi:main->main::@1] - __b1_from_main: jmp __b1 // main::@1 __b1: + // [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$10 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- // [7] call print_person // [9] phi from main::@1 to print_person [phi:main::@1->print_person] print_person_from___b1: @@ -414,15 +416,11 @@ main: { __breturn: // [8] return rts - jesper_name: .text "jesper" - .byte 0 - .fill 9, 0 - henriette_name: .text "henriette" - .byte 0 - .fill 6, 0 + jesper_name: .fill $10, 0 + henriette_name: .fill $10, 0 } // print_person -// print_person(byte zeropage(2) person_id, byte* zeropage(4) person_name) +// print_person(byte zp(2) person_id, byte* zp(4) person_name) print_person: { .label i = 6 .label person_id = 2 @@ -494,10 +492,19 @@ print_person: { // File Data DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill 9, 0 + __1: .text "henriette" + .byte 0 + .fill 6, 0 REGISTER UPLIFT POTENTIAL REGISTERS -Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a +Statement [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte a as potential for zp[1]:3 [ idx#13 idx#16 ] +Removing always clobbered register reg byte y as potential for zp[1]:3 [ idx#13 idx#16 ] +Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:8 [ idx#4 ] Statement [15] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a @@ -505,13 +512,15 @@ Removing always clobbered register reg byte a as potential for zp[1]:6 [ print_p Removing always clobbered register reg byte a as potential for zp[1]:7 [ idx#14 idx#5 idx#6 ] Statement [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a Statement [19] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a +Statement [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a Statement [15] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a Statement [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a Statement [19] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a Potential registers zp[1]:2 [ print_person::person_id#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:3 [ idx#13 idx#16 ] : zp[1]:3 , reg byte x , reg byte y , +Potential registers zp[1]:3 [ idx#13 idx#16 ] : zp[1]:3 , reg byte x , Potential registers zp[2]:4 [ print_person::person_name#4 ] : zp[2]:4 , Potential registers zp[1]:6 [ print_person::i#2 print_person::i#1 ] : zp[1]:6 , reg byte x , reg byte y , Potential registers zp[1]:7 [ idx#14 idx#5 idx#6 ] : zp[1]:7 , reg byte x , reg byte y , @@ -523,11 +532,14 @@ Uplift Scope [] 24.75: zp[1]:7 [ idx#14 idx#5 idx#6 ] 4: zp[1]:3 [ idx#13 idx#16 Uplift Scope [Person] Uplift Scope [main] -Uplifting [print_person] best 545 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp[2]:4 [ print_person::person_name#4 ] reg byte x [ print_person::person_id#2 ] -Uplifting [] best 463 combination reg byte x [ idx#14 idx#5 idx#6 ] reg byte y [ idx#13 idx#16 ] reg byte x [ idx#4 ] -Uplifting [Person] best 463 combination -Uplifting [main] best 463 combination -Allocated (was zp[2]:4) zp[2]:2 [ print_person::person_name#4 ] +Uplifting [print_person] best 577 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp[2]:4 [ print_person::person_name#4 ] reg byte x [ print_person::person_id#2 ] +Uplifting [] best 499 combination reg byte x [ idx#14 idx#5 idx#6 ] zp[1]:3 [ idx#13 idx#16 ] reg byte x [ idx#4 ] +Uplifting [Person] best 499 combination +Uplifting [main] best 499 combination +Attempting to uplift remaining variables inzp[1]:3 [ idx#13 idx#16 ] +Uplifting [] best 499 combination zp[1]:3 [ idx#13 idx#16 ] +Allocated (was zp[1]:3) zp[1]:2 [ idx#13 idx#16 ] +Allocated (was zp[2]:4) zp[2]:3 [ print_person::person_name#4 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -538,6 +550,7 @@ ASSEMBLER BEFORE OPTIMIZATION .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 + .label idx = 2 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -546,8 +559,6 @@ __b1_from___bbegin: // @1 __b1: // [2] call main - // [4] phi from @1 to main [phi:@1->main] -main_from___b1: jsr main // [3] phi from @1 to @end [phi:@1->@end] __bend_from___b1: @@ -558,6 +569,13 @@ __bend: main: { .const jesper_id = 4 .const henriette_id = 7 + // [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$10 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- // [5] call print_person // [9] phi from main to print_person [phi:main->print_person] print_person_from_main: @@ -566,16 +584,22 @@ main: { sta.z print_person.person_name lda #>jesper_name sta.z print_person.person_name+1 - // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1 - ldy #0 + // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1 + lda #0 + sta.z idx // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id [phi:main->print_person#2] -- vbuxx=vbuc1 ldx #jesper_id jsr print_person - // [6] phi from main to main::@1 [phi:main->main::@1] - __b1_from_main: jmp __b1 // main::@1 __b1: + // [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$10 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- // [7] call print_person // [9] phi from main::@1 to print_person [phi:main::@1->print_person] print_person_from___b1: @@ -593,23 +617,19 @@ main: { __breturn: // [8] return rts - jesper_name: .text "jesper" - .byte 0 - .fill 9, 0 - henriette_name: .text "henriette" - .byte 0 - .fill 6, 0 + jesper_name: .fill $10, 0 + henriette_name: .fill $10, 0 } // print_person -// print_person(byte register(X) person_id, byte* zeropage(2) person_name) +// print_person(byte register(X) person_id, byte* zp(3) person_name) print_person: { - .label person_name = 2 - // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx + .label person_name = 3 + // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuxx lda DIGIT,x + ldy.z idx sta SCREEN,y - // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy - tya - tax + // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuz1 + ldx.z idx inx // [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 lda #' ' @@ -634,10 +654,9 @@ print_person: { // [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 lda #' ' sta SCREEN,x - // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx - txa - tay - iny + // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuxx + inx + stx.z idx jmp __breturn // print_person::@return __breturn: @@ -661,6 +680,12 @@ print_person: { // File Data DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill 9, 0 + __1: .text "henriette" + .byte 0 + .fill 6, 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 @@ -674,14 +699,12 @@ Succesful ASM optimization Pass5NextJumpElimination Replacing label __bbegin with __b1 Removing instruction __bbegin: Removing instruction __b1_from___bbegin: -Removing instruction main_from___b1: Removing instruction __bend_from___b1: -Removing instruction __b1_from_main: -Removing instruction print_person_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __bend: Removing instruction print_person_from_main: Removing instruction __b1: +Removing instruction print_person_from___b1: Removing instruction __breturn: Removing instruction __b1_from_print_person: Removing instruction __b3: @@ -695,17 +718,19 @@ Removing instruction __b1: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE +(const byte*) $0[(number) $10] = (string) "jesper" +(const byte*) $1[(number) $10] = (string) "henriette" (label) @1 (label) @begin (label) @end -(const byte*) DIGIT = (string) "0123456789" +(const byte*) DIGIT[] = (string) "0123456789" (byte) Person::id -(const byte*) Person::name = { fill( $10, 0) } +(const byte*) Person::name[(number) $10] = { fill( $10, 0) } (const byte*) SCREEN = (byte*) 1024 (byte) idx -(byte) idx#13 reg byte y 3.0 +(byte) idx#13 idx zp[1]:2 3.0 (byte) idx#14 reg byte x 9.75 -(byte) idx#16 reg byte y 1.0 +(byte) idx#16 idx zp[1]:2 1.0 (byte) idx#4 reg byte x 3.0 (byte) idx#5 reg byte x 4.0 (byte) idx#6 reg byte x 11.0 @@ -713,10 +738,10 @@ FINAL SYMBOL TABLE (label) main::@1 (label) main::@return (const byte) main::henriette_id = (byte) 7 -(const byte*) main::henriette_name = (string) "henriette" +(const byte*) main::henriette_name[(number) $10] = { fill( $10, 0) } (const byte) main::jesper_id = (byte) 4 -(const byte*) main::jesper_name = (string) "jesper" -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(const byte*) main::jesper_name[(number) $10] = { fill( $10, 0) } +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 @@ -727,19 +752,19 @@ FINAL SYMBOL TABLE (struct Person) print_person::person (byte) print_person::person_id (byte) print_person::person_id#2 reg byte x 2.0 -(const byte*) print_person::person_name -(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 person_name zp[2]:3 2.2 reg byte x [ print_person::person_id#2 ] -reg byte y [ idx#13 idx#16 ] -zp[2]:2 [ print_person::person_name#4 ] +zp[1]:2 [ idx#13 idx#16 ] +zp[2]:3 [ print_person::person_name#4 ] reg byte y [ print_person::i#2 print_person::i#1 ] reg byte x [ idx#14 idx#5 idx#6 ] reg byte x [ idx#4 ] FINAL ASSEMBLER -Score: 382 +Score: 418 // File Comments // Example of a struct containing an array @@ -749,17 +774,25 @@ Score: 382 .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 + .label idx = 2 // @begin // [1] phi from @begin to @1 [phi:@begin->@1] // @1 // [2] call main - // [4] phi from @1 to main [phi:@1->main] // [3] phi from @1 to @end [phi:@1->@end] // @end // main main: { .const jesper_id = 4 .const henriette_id = 7 + // jesper = { 4, "jesper" } + // [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $10) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$10 + !: + lda __0-1,y + sta jesper_name-1,y + dey + bne !- // print_person(jesper) // [5] call print_person // [9] phi from main to print_person [phi:main->print_person] @@ -768,13 +801,21 @@ main: { sta.z print_person.person_name lda #>jesper_name sta.z print_person.person_name+1 - // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1 - ldy #0 + // [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1 + lda #0 + sta.z idx // [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id [phi:main->print_person#2] -- vbuxx=vbuc1 ldx #jesper_id jsr print_person - // [6] phi from main to main::@1 [phi:main->main::@1] // main::@1 + // henriette = { 7, "henriette" } + // [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $10) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3 + ldy #$10 + !: + lda __1-1,y + sta henriette_name-1,y + dey + bne !- // print_person(henriette) // [7] call print_person // [9] phi from main::@1 to print_person [phi:main::@1->print_person] @@ -791,25 +832,21 @@ main: { // } // [8] return rts - jesper_name: .text "jesper" - .byte 0 - .fill 9, 0 - henriette_name: .text "henriette" - .byte 0 - .fill 6, 0 + jesper_name: .fill $10, 0 + henriette_name: .fill $10, 0 } // print_person -// print_person(byte register(X) person_id, byte* zeropage(2) person_name) +// print_person(byte register(X) person_id, byte* zp(3) person_name) print_person: { - .label person_name = 2 + .label person_name = 3 // SCREEN[idx++] = DIGIT[person.id] - // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx + // [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuxx lda DIGIT,x + ldy.z idx sta SCREEN,y // SCREEN[idx++] = DIGIT[person.id]; - // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy - tya - tax + // [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuz1 + ldx.z idx inx // SCREEN[idx++] = ' ' // [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2 @@ -835,10 +872,9 @@ print_person: { lda #' ' sta SCREEN,x // SCREEN[idx++] = ' '; - // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx - txa - tay - iny + // [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuxx + inx + stx.z idx // print_person::@return // } // [18] return @@ -863,4 +899,10 @@ print_person: { // File Data DIGIT: .text "0123456789" .byte 0 + __0: .text "jesper" + .byte 0 + .fill 9, 0 + __1: .text "henriette" + .byte 0 + .fill 6, 0 diff --git a/src/test/ref/struct-ptr-34.sym b/src/test/ref/struct-ptr-34.sym index bd94342ad..c38b3b6f5 100644 --- a/src/test/ref/struct-ptr-34.sym +++ b/src/test/ref/struct-ptr-34.sym @@ -1,14 +1,16 @@ +(const byte*) $0[(number) $10] = (string) "jesper" +(const byte*) $1[(number) $10] = (string) "henriette" (label) @1 (label) @begin (label) @end -(const byte*) DIGIT = (string) "0123456789" +(const byte*) DIGIT[] = (string) "0123456789" (byte) Person::id -(const byte*) Person::name = { fill( $10, 0) } +(const byte*) Person::name[(number) $10] = { fill( $10, 0) } (const byte*) SCREEN = (byte*) 1024 (byte) idx -(byte) idx#13 reg byte y 3.0 +(byte) idx#13 idx zp[1]:2 3.0 (byte) idx#14 reg byte x 9.75 -(byte) idx#16 reg byte y 1.0 +(byte) idx#16 idx zp[1]:2 1.0 (byte) idx#4 reg byte x 3.0 (byte) idx#5 reg byte x 4.0 (byte) idx#6 reg byte x 11.0 @@ -16,10 +18,10 @@ (label) main::@1 (label) main::@return (const byte) main::henriette_id = (byte) 7 -(const byte*) main::henriette_name = (string) "henriette" +(const byte*) main::henriette_name[(number) $10] = { fill( $10, 0) } (const byte) main::jesper_id = (byte) 4 -(const byte*) main::jesper_name = (string) "jesper" -(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name) +(const byte*) main::jesper_name[(number) $10] = { fill( $10, 0) } +(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (label) print_person::@1 (label) print_person::@2 (label) print_person::@3 @@ -30,12 +32,12 @@ (struct Person) print_person::person (byte) print_person::person_id (byte) print_person::person_id#2 reg byte x 2.0 -(const byte*) print_person::person_name -(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 +(byte*) print_person::person_name +(byte*) print_person::person_name#4 person_name zp[2]:3 2.2 reg byte x [ print_person::person_id#2 ] -reg byte y [ idx#13 idx#16 ] -zp[2]:2 [ print_person::person_name#4 ] +zp[1]:2 [ idx#13 idx#16 ] +zp[2]:3 [ print_person::person_name#4 ] reg byte y [ print_person::i#2 print_person::i#1 ] reg byte x [ idx#14 idx#5 idx#6 ] reg byte x [ idx#4 ] diff --git a/src/test/ref/struct-ptr-9.log b/src/test/ref/struct-ptr-9.log index ac6a38b74..742060f18 100644 --- a/src/test/ref/struct-ptr-9.log +++ b/src/test/ref/struct-ptr-9.log @@ -1,8 +1,9 @@ Fixing pointer array-indexing *((const struct Point*) points + (byte) main::i) Fixing pointer array-indexing *((const struct Point*) points + (byte) main::i1) Fixing pointer array-indexing *((const struct Point*) main::SCREEN + (byte) main::i1) -Adding struct value list initializer *((byte*~) main::$4 + (byte~) main::$2) ← (number) 2 -Adding struct value list initializer *((byte*~) main::$5 + (byte~) main::$2) ← (byte) main::i +Constantified RValue *((const struct Point*) points + (byte~) main::$2) ← (struct Point){ (byte) 2, (byte) main::i } +Adding struct value member variable copy *((byte*~) main::$4 + (byte~) main::$2) ← (byte) 2 +Adding struct value member variable copy *((byte*~) main::$5 + (byte~) main::$2) ← (byte) main::i Adding struct value member variable copy *((byte*~) main::$6 + (byte~) main::$3) ← *((byte*~) main::$7 + (byte~) main::$3) Adding struct value member variable copy *((byte*~) main::$8 + (byte~) main::$3) ← *((byte*~) main::$9 + (byte~) main::$3) Culled Empty Block (label) main::@4 @@ -19,7 +20,7 @@ main::@1: scope:[main] from main main::@1 (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) (byte~) main::$2 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_POINT (byte*~) main::$4 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_X - *((byte*~) main::$4 + (byte~) main::$2) ← (number) 2 + *((byte*~) main::$4 + (byte~) main::$2) ← (byte) 2 (byte*~) main::$5 ← (byte*)(const struct Point*) points + (const byte) OFFSET_STRUCT_POINT_Y *((byte*~) main::$5 + (byte~) main::$2) ← (byte) main::i#2 (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,1) @@ -88,15 +89,8 @@ SYMBOL TABLE SSA (byte) main::i1#2 (const struct Point*) points[(number) 2] = { fill( 2, 0) } -Adding number conversion cast (unumber) 2 in *((byte*~) main::$4 + (byte~) main::$2) ← (number) 2 -Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast *((byte*~) main::$4 + (byte~) main::$2) ← (unumber)(number) 2 -Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (struct Point*) 1024 -Simplifying constant integer cast 2 Successful SSA optimization PassNCastSimplification -Finalized unsigned number type (byte) 2 -Successful SSA optimization PassNFinalizeNumberTypeConversions Simple Condition (bool~) main::$0 [9] if((byte) main::i#1!=rangelast(0,1)) goto main::@1 Simple Condition (bool~) main::$1 [21] if((byte) main::i1#1!=rangelast(0,1)) goto main::@3 Successful SSA optimization Pass2ConditionalJumpSimplification