1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-11 20:37:40 +00:00

Implemented support for nested struct values.

This commit is contained in:
jespergravgaard 2019-06-09 10:47:33 +02:00
parent 26698851ca
commit 1540e14067
67 changed files with 769 additions and 727 deletions

@ -1,5 +1,5 @@
lda ({z1}),y
sta {c1},y
sta {c1},x
iny
lda ({z1}),y
sta {c1}+1,y
sta {c1}+1,x

@ -6,6 +6,7 @@ import dk.camelot64.kickc.model.statements.StatementInfos;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.values.VariableRef;
import dk.camelot64.kickc.passes.Pass1UnwindStructValues;
import java.nio.file.Path;
import java.util.ArrayList;
@ -71,8 +72,10 @@ public class Program {
private List<Number> reservedZps;
/** Absolute start address of the code. Null to start ad 0x080d. */
private Number programPc;
/** Cached phi transisitons into each block. */
Map<LabelRef, PhiTransitions> phiTransitions;
/** Cached phi transitions into each block. */
private Map<LabelRef, PhiTransitions> phiTransitions;
/** Struct values unwound to individual variables. */
private Pass1UnwindStructValues.StructUnwinding structUnwinding;
public Program() {
this.scope = new ProgramScope();
@ -83,6 +86,14 @@ public class Program {
this.reservedZps = new ArrayList<>();
}
public Pass1UnwindStructValues.StructUnwinding getStructUnwinding() {
return structUnwinding;
}
public void setStructUnwinding(Pass1UnwindStructValues.StructUnwinding structUnwinding) {
this.structUnwinding = structUnwinding;
}
public Map<LabelRef, PhiTransitions> getPhiTransitions() {
return phiTransitions;
}

@ -11,6 +11,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/** Convert all struct values that are not used as pointers (address-of used or declared volatile) into variables representing each member */
public class Pass1UnwindStructValues extends Pass1Base {
@ -22,23 +23,30 @@ public class Pass1UnwindStructValues extends Pass1Base {
@Override
public boolean step() {
boolean modified = false;
StructUnwinding structUnwinding = getProgram().getStructUnwinding();
if(structUnwinding == null) {
structUnwinding = new StructUnwinding();
getProgram().setStructUnwinding(structUnwinding);
}
// Iterate through all scopes generating member-variables for each struct
StructUnwinding structUnwinding = unwindAllStructVariables();
modified |= unwindAllStructVariables(structUnwinding);
// Unwind all procedure declaration parameters
unwindProcedureParameters(structUnwinding);
modified |= unwindProcedureParameters(structUnwinding);
// Unwind all usages of struct values
unwindStructReferences(structUnwinding);
modified |= unwindStructReferences(structUnwinding);
// Change all usages of members of struct values
unwindMemberReferences(structUnwinding);
modified |= unwindMemberReferences(structUnwinding);
return modified;
}
/**
* Unwins all usages of struct value references (in statements such as assignments.)
* Unwinds all usages of struct value references (in statements such as assignments.)
*
* @param structUnwinding Information about all unwound struct variables
*/
private void unwindStructReferences(StructUnwinding structUnwinding) {
private boolean unwindStructReferences(StructUnwinding structUnwinding) {
boolean modified = false;
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
@ -48,14 +56,15 @@ public class Pass1UnwindStructValues extends Pass1Base {
if(assignment.getlValue() instanceof VariableRef) {
Variable assignedVar = getScope().getVariable((VariableRef) assignment.getlValue());
if(assignedVar.getType() instanceof SymbolTypeStruct) {
unwindAssignment(assignment, assignedVar, stmtIt, structUnwinding);
modified |= unwindAssignment(assignment, assignedVar, stmtIt, structUnwinding);
}
}
} else if(statement instanceof StatementCall) {
unwindCall((StatementCall) statement, structUnwinding);
modified |= unwindCall((StatementCall) statement, structUnwinding);
}
}
}
return modified;
}
/**
@ -63,7 +72,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
*
* @param structUnwinding Information about all unwound struct variables
*/
private void unwindMemberReferences(StructUnwinding structUnwinding) {
private boolean unwindMemberReferences(StructUnwinding structUnwinding) {
AtomicBoolean modified = new AtomicBoolean(false);
ProgramValueIterator.execute(
getProgram(), (programValue, currentStmt, stmtIt, currentBlock) ->
{
@ -76,10 +86,12 @@ public class Pass1UnwindStructValues extends Pass1Base {
VariableRef structMemberVariable = memberVariables.getMemberUnwinding(structMemberRef.getMemberName());
getLog().append("Replacing struct member reference " + structMemberRef.toString(getProgram()) + " with member variable reference " + structMemberVariable.toString(getProgram()));
programValue.set(structMemberVariable);
modified.set(true);
}
}
}
});
return modified.get();
}
/**
@ -88,7 +100,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
* @param statementCall The call to unwind
* @param structUnwinding Information about all unwound struct variables
*/
private void unwindCall(StatementCall statementCall, StructUnwinding structUnwinding) {
private boolean unwindCall(StatementCall statementCall, StructUnwinding structUnwinding) {
//Procedure procedure = getScope().getProcedure(statementCall.getProcedure());
ArrayList<RValue> unwoundParameters = new ArrayList<>();
boolean anyUnwound = false;
@ -117,6 +129,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
statementCall.setParameters(unwoundParameters);
getLog().append("Converted procedure struct value parameter to member variables in call " + statementCall.toString(getProgram(), false));
}
return anyUnwound;
}
/**
@ -124,7 +137,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
*
* @param structUnwinding Information about all unwound struct variables (including procedure parameters)
*/
private void unwindProcedureParameters(StructUnwinding structUnwinding) {
private boolean unwindProcedureParameters(StructUnwinding structUnwinding) {
boolean modified = false;
// Iterate through all procedures changing parameter lists by unwinding each struct value parameter
for(Procedure procedure : getScope().getAllProcedures(true)) {
ArrayList<String> unwoundParameterNames = new ArrayList<>();
@ -143,8 +157,10 @@ public class Pass1UnwindStructValues extends Pass1Base {
if(procedureUnwound) {
procedure.setParameterNames(unwoundParameterNames);
getLog().append("Converted procedure struct value parameter to member variables " + procedure.toString(getProgram()));
modified = true;
}
}
return modified;
}
/**
@ -152,33 +168,37 @@ public class Pass1UnwindStructValues extends Pass1Base {
*
* @return Information about all unwound struct variables
*/
private StructUnwinding unwindAllStructVariables() {
// Maps struct variable to map from member name to the variable
StructUnwinding structUnwinding = new StructUnwinding();
private boolean unwindAllStructVariables(StructUnwinding structUnwinding) {
boolean modified = false;
// Iterate through all scopes generating member-variables for each struct
for(Variable variable : getScope().getAllVariables(true)) {
if(variable.getType() instanceof SymbolTypeStruct) {
if(!variable.isDeclaredVolatile() && !Pass2ConstantIdentification.isAddressOfUsed(variable.getRef(), getProgram())) {
// A non-volatile struct variable
Scope scope = variable.getScope();
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef());
for(Variable member : structDefinition.getAllVariables(false)) {
Variable memberVariable;
if(variable.getRef().isIntermediate()) {
memberVariable = scope.add(new VariableIntermediate(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType()));
} else {
memberVariable = scope.addVariable(variable.getLocalName() + "_" + member.getLocalName(), member.getType());
if(structUnwinding.getVariableUnwinding(variable.getRef()) == null) {
if(!variable.isDeclaredVolatile() && !Pass2ConstantIdentification.isAddressOfUsed(variable.getRef(), getProgram())) {
// A non-volatile struct variable
Scope scope = variable.getScope();
if(!(scope instanceof StructDefinition)) {
// Not inside another struct
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef());
for(Variable member : structDefinition.getAllVariables(false)) {
Variable memberVariable;
if(variable.getRef().isIntermediate()) {
memberVariable = scope.add(new VariableIntermediate(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType()));
} else {
memberVariable = scope.addVariable(variable.getLocalName() + "_" + member.getLocalName(), member.getType());
}
variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef());
getLog().append("Created struct value member variable " + memberVariable.toString(getProgram()));
}
getLog().append("Converted struct value to member variables " + variable.toString(getProgram()));
modified = true;
}
variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef());
getLog().append("Created struct value member variable " + memberVariable.toString(getProgram()));
}
getLog().append("Converted struct value to member variables " + variable.toString(getProgram()));
}
}
}
return structUnwinding;
return modified;
}
/**
@ -189,7 +209,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
* @param stmtIt The statement iterator used for adding/removing statements
* @param structUnwinding Information about unwound struct value variables
*/
private void unwindAssignment(StatementAssignment assignment, Variable assignedVar, ListIterator<Statement> stmtIt, StructUnwinding structUnwinding) {
private boolean unwindAssignment(StatementAssignment assignment, Variable assignedVar, ListIterator<Statement> stmtIt, StructUnwinding structUnwinding) {
boolean modified = false;
// Assigning a struct!
if(assignment.getOperator() == null && assignment.getrValue2() instanceof StructZero) {
// Initializing a struct - unwind to assigning zero to each member!
@ -205,6 +226,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
}
stmtIt.next();
stmtIt.remove();
modified = true;
}
} else if(assignment.getOperator() == null && assignment.getrValue2() instanceof VariableRef) {
Variable sourceVar = getScope().getVariable((VariableRef) assignment.getrValue2());
@ -223,6 +245,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
}
stmtIt.next();
stmtIt.remove();
modified = true;
}
} else {
throw new CompileError("Incompatible struct assignment " + assignment.toString(getProgram(), false), assignment);
@ -245,10 +268,12 @@ public class Pass1UnwindStructValues extends Pass1Base {
}
stmtIt.next();
stmtIt.remove();
modified = true;
}
} else {
throw new CompileError("Incompatible struct assignment " + assignment.toString(getProgram(), false), assignment);
}
return modified;
}
/**

@ -70,6 +70,11 @@ public class TestPrograms {
assertError("struct-err-0", "Unknown struct type");
}
@Test
public void testStruct6() throws IOException, URISyntaxException {
compileAndCompare("struct-6");
}
//@Test
//public void testStruct5() throws IOException, URISyntaxException {
// compileAndCompare("struct-5", log().verboseParse().verboseCreateSsa());
@ -2239,8 +2244,8 @@ public class TestPrograms {
ReferenceHelper helper = new ReferenceHelperFolder(refPath);
success &= helper.testOutput(fileName, ".asm", program.getAsm().toString(false));
success &= helper.testOutput(fileName, ".sym", program.getScope().toString(program));
//success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program));
//success &= helper.testOutput(fileName, ".log", program.getLog().toString());
success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program));
success &= helper.testOutput(fileName, ".log", program.getLog().toString());
if(!success) {
//System.out.println("\nCOMPILE LOG");
//System.out.println(program.getLog().toString());

20
src/test/kc/struct-6.kc Normal file

@ -0,0 +1,20 @@
// Minimal struct - nesting structs
struct Point {
byte x;
byte y;
};
struct Circle {
struct Point center;
byte radius;
};
void main() {
struct Point p = { 10, 10 };
struct Circle c = { p, 5 };
const byte* SCREEN = 0x0400;
SCREEN[0] = c.center.x;
SCREEN[1] = c.center.y;
SCREEN[2] = c.radius;
}

@ -42,7 +42,7 @@ Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -98,7 +98,7 @@ Adding pointer type conversion cast (byte*) CHARSET8 in (byte*) CHARSET8 ← (nu
Adding pointer type conversion cast (byte*) gfx_init_plane_charset8::gfxa in (byte*) gfx_init_plane_charset8::gfxa ← (number~) gfx_init_plane_charset8::$5
Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -98,7 +98,7 @@ Adding pointer type conversion cast (byte*) gfx_init_chunky::gfxb in (byte*) gfx
Adding pointer type conversion cast (byte*) gfx_init_chunky::gfxb in (byte*) gfx_init_chunky::gfxb ← (number) $4000
Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -96,7 +96,7 @@ Adding pointer type conversion cast (byte*) DTV_BLITTER_CONTROL2 in (byte*) DTV_
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -96,7 +96,7 @@ Adding pointer type conversion cast (byte*) DTV_BLITTER_CONTROL2 in (byte*) DTV_
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -95,7 +95,7 @@ Adding pointer type conversion cast (byte*) DTV_BLITTER_ALU in (byte*) DTV_BLITT
Adding pointer type conversion cast (byte*) DTV_BLITTER_CONTROL2 in (byte*) DTV_BLITTER_CONTROL2 ← (number) $d33f
Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -118,7 +118,7 @@ Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Identified constant variable (byte) form_fields_cnt
Identified constant variable (byte) gfx_init_vic_bitmap::lines_cnt
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -138,7 +138,7 @@ Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank
Identified constant variable (byte*) DTV_BLITTER_ALU
Identified constant variable (byte) mode_stdbitmap::lines_cnt
Identified constant variable (byte*) mode_8bpppixelcell::CHARGEN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -1,6 +1,6 @@
Fixing pointer array-indexing *((byte*[]) screens + (byte) getScreen::id)
Inlined call (byte*~) main::$0 ← call getScreen (number) 0
Inlined call (byte*~) main::$1 ← call spritePtr (byte*) main::screen
Inlined call [4] (byte*~) main::$0 ← call getScreen (number) 0
Inlined call [6] (byte*~) main::$1 ← call spritePtr (byte*) main::screen
Culled Empty Block (label) main::getScreen1_@1
Culled Empty Block (label) main::spritePtr1_@1
Culled Empty Block (label) @1

@ -1,8 +1,8 @@
Fixing pointer array-indexing *((byte*[]) screens + (byte) getScreen::id)
Adding pointer type conversion cast (byte*) main::DSP in (byte*) main::DSP ← (number) $400
Identified constant variable (byte*) main::DSP
Inlined call (byte*~) main::$0 ← call getScreen (number) 0
Inlined call (byte~) main::$1 ← call spritePtr (byte*~) main::$0
Inlined call [4] (byte*~) main::$0 ← call getScreen (number) 0
Inlined call [5] (byte~) main::$1 ← call spritePtr (byte*~) main::$0
Culled Empty Block (label) main::getScreen1_@1
Culled Empty Block (label) main::spritePtr1_@1
Culled Empty Block (label) @1

@ -64,12 +64,12 @@ Identified constant variable (byte) level
Identified constant variable (byte) game_over
Identified constant variable (byte*) SIN
Identified constant variable (byte*) SIN_SPRITE
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) $5 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call (byte~) sprites_irq::$5 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call call vicSelectGfxBank (byte*) PLAYFIELD_SCREEN_1
Inlined call (byte~) main::$1 ← call toD018 (byte*) PLAYFIELD_SCREEN_1 (byte*) PLAYFIELD_CHARSET
Inlined call (byte~) main::$7 ← call toSpritePtr (byte*) SIN_SPRITE
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [159] (byte~) $5 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call [206] (byte~) sprites_irq::$5 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call [225] call vicSelectGfxBank (byte*) PLAYFIELD_SCREEN_1
Inlined call [226] (byte~) main::$1 ← call toD018 (byte*) PLAYFIELD_SCREEN_1 (byte*) PLAYFIELD_CHARSET
Inlined call [239] (byte~) main::$7 ← call toSpritePtr (byte*) SIN_SPRITE
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -81,13 +81,13 @@ Adding pointer type conversion cast (byte*) render_next::next_piece_gfx in (byte
Adding pointer type conversion cast (byte*) current_piece in (byte*) current_piece ← (number) 0
Adding pointer type conversion cast (byte*) current_piece in (byte*) current_piece ← *((word[]) PIECES + (byte~) play_spawn_current::$7)
Identified constant variable (byte) render_screen_original::SPACE
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call vicSelectGfxBank (byte*) PLAYFIELD_CHARSET
Inlined call (byte~) render_show::$2 ← call toD018 (byte*) PLAYFIELD_SCREEN_1 (byte*) PLAYFIELD_CHARSET
Inlined call (byte~) render_show::$1 ← call toD018 (byte*) PLAYFIELD_SCREEN_2 (byte*) PLAYFIELD_CHARSET
Inlined call (byte~) $6 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call (byte~) sprites_irq::$5 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call (byte~) play_spawn_current::$5 ← call sid_rnd
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [341] call vicSelectGfxBank (byte*) PLAYFIELD_CHARSET
Inlined call [378] (byte~) render_show::$2 ← call toD018 (byte*) PLAYFIELD_SCREEN_1 (byte*) PLAYFIELD_CHARSET
Inlined call [380] (byte~) render_show::$1 ← call toD018 (byte*) PLAYFIELD_SCREEN_2 (byte*) PLAYFIELD_CHARSET
Inlined call [572] (byte~) $6 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call [619] (byte~) sprites_irq::$5 ← call toSpritePtr (byte*) PLAYFIELD_SPRITES
Inlined call [879] (byte~) play_spawn_current::$5 ← call sid_rnd
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -27,10 +27,10 @@ print: {
ldy #2
tax
lda (m),y
sta SCREEN,y
sta SCREEN,x
iny
lda (m),y
sta SCREEN+1,y
sta SCREEN+1,x
inc screen_idx
rts
}

@ -306,10 +306,10 @@ print: {
ldx _2
ldy #2
lda (m),y
sta SCREEN,y
sta SCREEN,x
iny
lda (m),y
sta SCREEN+1,y
sta SCREEN+1,x
//SEG26 [12] (byte) screen_idx#11 ← ++ (byte) screen_idx#10 -- vbuz1=_inc_vbuz1
inc screen_idx
jmp breturn
@ -415,10 +415,10 @@ print: {
ldy #2
tax
lda (m),y
sta SCREEN,y
sta SCREEN,x
iny
lda (m),y
sta SCREEN+1,y
sta SCREEN+1,x
//SEG26 [12] (byte) screen_idx#11 ← ++ (byte) screen_idx#10 -- vbuz1=_inc_vbuz1
inc screen_idx
jmp breturn
@ -541,10 +541,10 @@ print: {
ldy #2
tax
lda (m),y
sta SCREEN,y
sta SCREEN,x
iny
lda (m),y
sta SCREEN+1,y
sta SCREEN+1,x
//SEG26 [12] (byte) screen_idx#11 ← ++ (byte) screen_idx#10 -- vbuz1=_inc_vbuz1
inc screen_idx
//SEG27 print::@return

@ -177,19 +177,19 @@ Identified constant variable (byte*) SINH_LO
Identified constant variable (byte*) SINH_HI
Identified constant variable (byte*) SINQ_LO
Identified constant variable (byte*) SINQ_HI
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call print_sbyte_pos (signed byte) sx (number) 0 (number) $25
Inlined call call print_sbyte_pos (signed byte) sy (number) 1 (number) $25
Inlined call call print_sbyte_pos (signed byte) sz (number) 2 (number) $25
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 0) (number) 4 (number) $1d
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 1) (number) 4 (number) $21
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 2) (number) 4 (number) $25
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 3) (number) 5 (number) $1d
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 4) (number) 5 (number) $21
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 5) (number) 5 (number) $25
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 6) (number) 6 (number) $1d
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 7) (number) 6 (number) $21
Inlined call call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 8) (number) 6 (number) $25
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [415] call print_sbyte_pos (signed byte) sx (number) 0 (number) $25
Inlined call [416] call print_sbyte_pos (signed byte) sy (number) 1 (number) $25
Inlined call [417] call print_sbyte_pos (signed byte) sz (number) 2 (number) $25
Inlined call [418] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 0) (number) 4 (number) $1d
Inlined call [419] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 1) (number) 4 (number) $21
Inlined call [420] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 2) (number) 4 (number) $25
Inlined call [421] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 3) (number) 5 (number) $1d
Inlined call [422] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 4) (number) 5 (number) $21
Inlined call [423] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 5) (number) 5 (number) $25
Inlined call [424] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 6) (number) 6 (number) $1d
Inlined call [425] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 7) (number) 6 (number) $21
Inlined call [426] call print_sbyte_pos *((signed byte[9]) rotation_matrix + (number) 8) (number) 6 (number) $25
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -58,7 +58,7 @@ Identified constant variable (signed byte*) zr
Identified constant variable (word*) psp1
Identified constant variable (word*) psp2
Identified constant variable (signed byte*) PERSP_Z
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -49,7 +49,7 @@ Adding pointer type conversion cast (byte*) bitmap_plot::plotter in (byte*) bitm
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Adding pointer type conversion cast (byte*) BITMAP in (byte*) BITMAP ← (number) $2000
Identified constant variable (byte) lines_cnt
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -44,7 +44,7 @@ Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_I
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Identified constant variable (byte*) SCREEN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -55,9 +55,9 @@ Identified constant variable (byte*) SCREEN1
Identified constant variable (byte*) SCREEN2
Identified constant variable (byte*) BUFFER
Identified constant variable (byte*) CHARSET
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) main::$7 ← call toD018 (byte*) SCREEN1 (byte*) CHARSET
Inlined call (byte~) main::$9 ← call toD018 (byte*) SCREEN2 (byte*) CHARSET
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [142] (byte~) main::$7 ← call toD018 (byte*) SCREEN1 (byte*) CHARSET
Inlined call [145] (byte~) main::$9 ← call toD018 (byte*) SCREEN2 (byte*) CHARSET
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -45,7 +45,7 @@ Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTER
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) GHOST_BYTE in (byte*) GHOST_BYTE ← (number) $3fff
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -52,11 +52,11 @@ Adding pointer type conversion cast (byte*) YSIN in (byte*) YSIN ← (number) $2
Identified constant variable (byte*) SCREEN
Identified constant variable (byte*) SPRITE
Identified constant variable (byte*) YSIN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call plexSetScreen (byte*) plexInit::screen
Inlined call call plexFreePrepare
Inlined call call plexFreeAdd (byte) plexShowSprite::ypos
Inlined call (byte~) loop::$7 ← call plexFreeNextYpos
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [118] call plexSetScreen (byte*) plexInit::screen
Inlined call [153] call plexFreePrepare
Inlined call [159] call plexFreeAdd (byte) plexShowSprite::ypos
Inlined call [258] (byte~) loop::$7 ← call plexFreeNextYpos
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -43,7 +43,7 @@ Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTER
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) MUSIC in (byte*) MUSIC ← (number) $1000
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -44,7 +44,7 @@ Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTER
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) MUSIC in (byte*) MUSIC ← (number) $1000
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -51,8 +51,8 @@ Adding pointer type conversion cast (byte*) SID_VOICE3_OSC in (byte*) SID_VOICE3
Adding pointer type conversion cast (byte*) SCREEN1 in (byte*) SCREEN1 ← (number) $2800
Adding pointer type conversion cast (byte*) CHARSET in (byte*) CHARSET ← (number) $2000
Adding pointer type conversion cast (byte*) SINTABLE in (byte*) SINTABLE ← (number) $1f00
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) main::$1 ← call toD018 (byte*) SCREEN1 (byte*) CHARSET
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [265] (byte~) main::$1 ← call toD018 (byte*) SCREEN1 (byte*) CHARSET
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -52,9 +52,9 @@ Adding pointer type conversion cast (byte*) SCREEN1 in (byte*) SCREEN1 ← (numb
Adding pointer type conversion cast (byte*) SCREEN2 in (byte*) SCREEN2 ← (number) $2c00
Adding pointer type conversion cast (byte*) CHARSET in (byte*) CHARSET ← (number) $2000
Adding pointer type conversion cast (byte*) SINTABLE in (byte*) SINTABLE ← (number) $1f00
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) main::$4 ← call toD018 (byte*) SCREEN1 (byte*) CHARSET
Inlined call (byte~) main::$6 ← call toD018 (byte*) SCREEN2 (byte*) CHARSET
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [268] (byte~) main::$4 ← call toD018 (byte*) SCREEN1 (byte*) CHARSET
Inlined call [271] (byte~) main::$6 ← call toD018 (byte*) SCREEN2 (byte*) CHARSET
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -42,7 +42,7 @@ Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -57,10 +57,10 @@ Adding pointer type conversion cast (byte*) SPRITE in (byte*) SPRITE ← (number
Identified constant variable (byte*) SCREEN
Identified constant variable (byte*) COS
Identified constant variable (byte*) SPRITE
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call mulf8s_prepare (signed byte) mulf8s::a
Inlined call call mulf8s_prepare (signed byte) anim::cos_a
Inlined call call mulf8s_prepare (signed byte) anim::sin_a
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [205] call mulf8s_prepare (signed byte) mulf8s::a
Inlined call [280] call mulf8s_prepare (signed byte) anim::cos_a
Inlined call [287] call mulf8s_prepare (signed byte) anim::sin_a
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -50,8 +50,8 @@ Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number
Adding pointer type conversion cast (byte*) LOGO in (byte*) LOGO ← (number) $2000
Identified constant variable (byte*) SCREEN
Identified constant variable (byte*) LOGO
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) main::$0 ← call toD018 (byte*) SCREEN (byte*) LOGO
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [543] (byte~) main::$0 ← call toD018 (byte*) SCREEN (byte*) LOGO
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -46,8 +46,8 @@ Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number
Adding pointer type conversion cast (byte*) LOGO in (byte*) LOGO ← (number) $2000
Identified constant variable (byte*) SCREEN
Identified constant variable (byte*) LOGO
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) main::$0 ← call toD018 (byte*) SCREEN (byte*) LOGO
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [117] (byte~) main::$0 ← call toD018 (byte*) SCREEN (byte*) LOGO
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -53,9 +53,9 @@ Adding pointer type conversion cast (signed word*) sin2 in (signed word*) sin2
Identified constant variable (byte*) SCREEN
Identified constant variable (byte*) BITMAP
Identified constant variable (signed word*) sin2
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call vicSelectGfxBank (byte*) SCREEN
Inlined call (byte~) main::$4 ← call toD018 (byte*) SCREEN (byte*) BITMAP
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [608] call vicSelectGfxBank (byte*) SCREEN
Inlined call [610] (byte~) main::$4 ← call toD018 (byte*) SCREEN (byte*) BITMAP
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -50,7 +50,7 @@ Adding pointer type conversion cast (byte*) sprites in (byte*) sprites ← (numb
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Adding pointer type conversion cast (byte*) gen_sintab::f_2pi in (byte*) gen_sintab::f_2pi ← (number) $e2e5
Identified constant variable (byte*) gen_sintab::f_2pi
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -43,8 +43,8 @@ Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTER
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) main::PLAYFIELD_CHARSET in (byte*) main::PLAYFIELD_CHARSET ← (number) $2800
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call vicSelectGfxBank (byte*) main::PLAYFIELD_CHARSET
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [109] call vicSelectGfxBank (byte*) main::PLAYFIELD_CHARSET
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -1,8 +1,8 @@
Adding pointer type conversion cast (byte*) screen in (byte*) screen ← (number) $400
Identified constant variable (byte*) screen
Identified constant variable (byte*) main::hello
Inlined call call print2 (byte*) screen (byte*) main::hello
Inlined call call print2 (byte*~) main::$1 (byte*) main::hello
Inlined call [2] call print2 (byte*) screen (byte*) main::hello
Inlined call [4] call print2 (byte*~) main::$1 (byte*) main::hello
Culled Empty Block (label) main::print21_@2
Culled Empty Block (label) main::print21_@return
Culled Empty Block (label) main::print22_@2

@ -1,7 +1,7 @@
Adding pointer type conversion cast (byte*) screen in (byte*) screen ← (number) $400
Identified constant variable (byte*) screen
Inlined call (byte~) main::$0 ← call toUpper (byte) 'c' true
Inlined call (byte~) main::$1 ← call toUpper (byte) 'm' false
Inlined call [1] (byte~) main::$0 ← call toUpper (byte) 'c' true
Inlined call [3] (byte~) main::$1 ← call toUpper (byte) 'm' false
Culled Empty Block (label) main::toUpper1_@3
Culled Empty Block (label) main::toUpper2_@3
Culled Empty Block (label) @1

@ -2,11 +2,11 @@ Adding pointer type conversion cast (byte*) main::sc in (byte*) main::sc ← (nu
Adding pointer type conversion cast (byte*) cur_line in (byte*) cur_line ← (number) $400
Adding pointer type conversion cast (byte*) cur_line in (byte*) cur_line ← (number) $400
Identified literal word (word) { line::xpos, 0 } in (word) line::pos ← { (byte) line::xpos, (number) 0 }
Inlined call call line (number) 2 (number) $40 (number) $a (byte) '*'
Inlined call [6] call line (number) 2 (number) $40 (number) $a (byte) '*'
Inlined call call plot (byte~) main::line1_$0 (byte) main::line1_ch
Inlined call call line (number) 4 (number) $80 (number) $f (byte) '.'
Inlined call [7] call line (number) 4 (number) $80 (number) $f (byte) '.'
Inlined call call plot (byte~) main::line2_$0 (byte) main::line2_ch
Inlined call call plot (byte~) line::$0 (byte) line::ch
Inlined call [14] call plot (byte~) line::$0 (byte) line::ch
Culled Empty Block (label) main::plot1_@return
Culled Empty Block (label) main::line1_@2
Culled Empty Block (label) main::line1_@return

@ -1,8 +1,8 @@
Adding pointer type conversion cast (byte*) screen in (byte*) screen ← (number) $400
Identified constant variable (byte*) screen
Inlined call (byte~) main::$0 ← call sum (number) 2 (number) 1
Inlined call (byte~) main::$1 ← call sum (number) $a (number) 3
Inlined call (byte~) main::$2 ← call sum (number) 4 (number) 8
Inlined call [1] (byte~) main::$0 ← call sum (number) 2 (number) 1
Inlined call [3] (byte~) main::$1 ← call sum (number) $a (number) 3
Inlined call [5] (byte~) main::$2 ← call sum (number) 4 (number) 8
Culled Empty Block (label) main::sum1_@1
Culled Empty Block (label) main::sum2_@1
Culled Empty Block (label) main::sum3_@1

@ -1,8 +1,8 @@
Adding pointer type conversion cast (byte*) screen in (byte*) screen ← (number) $400
Identified constant variable (byte*) screen
Identified constant variable (byte*) main::hello
Inlined call call print (byte*) screen (byte*) main::hello
Inlined call call print (byte*~) main::$2 (byte*) main::hello
Inlined call [2] call print (byte*) screen (byte*) main::hello
Inlined call [5] call print (byte*~) main::$2 (byte*) main::hello
Culled Empty Block (label) main::print1_@2
Culled Empty Block (label) main::print1_@return
Culled Empty Block (label) main::print2_@2

@ -10,8 +10,8 @@ Identified constant variable (byte*) BGCOL
Identified constant variable (byte*) screen
Identified constant variable (byte*) charset1
Identified constant variable (byte*) charset2
Inlined call (byte~) main::$1 ← call toD018 (byte*) screen (byte*) charset1
Inlined call (byte~) main::$3 ← call toD018 (byte*) screen (byte*) charset2
Inlined call [10] (byte~) main::$1 ← call toD018 (byte*) screen (byte*) charset1
Inlined call [15] (byte~) main::$3 ← call toD018 (byte*) screen (byte*) charset2
Culled Empty Block (label) main::@2
Culled Empty Block (label) main::@17
Culled Empty Block (label) main::@3

@ -43,7 +43,7 @@ Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -45,7 +45,7 @@ Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_I
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Adding pointer type conversion cast (byte*) VIC_BASE in (byte*) VIC_BASE ← (number) $d000
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -43,7 +43,7 @@ Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -44,7 +44,7 @@ Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_I
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Identified constant variable (byte*) SCREEN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -53,11 +53,11 @@ Adding pointer type conversion cast (byte*) BITMAP in (byte*) BITMAP ← (number
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $8800
Identified constant variable (byte*) BITMAP
Identified constant variable (byte*) SCREEN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call vicSelectGfxBank (byte*) SCREEN
Inlined call (byte~) main::$4 ← call toD018 (byte*) SCREEN (byte*) BITMAP
Inlined call (word~) point_init::$6 ← call abs16s (signed word) point_init::x_diff
Inlined call (word~) point_init::$7 ← call abs16s (signed word) point_init::y_diff
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [290] call vicSelectGfxBank (byte*) SCREEN
Inlined call [291] (byte~) main::$4 ← call toD018 (byte*) SCREEN (byte*) BITMAP
Inlined call [319] (word~) point_init::$6 ← call abs16s (signed word) point_init::x_diff
Inlined call [320] (word~) point_init::$7 ← call abs16s (signed word) point_init::y_diff
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -53,11 +53,11 @@ Adding pointer type conversion cast (byte*) YSIN in (byte*) YSIN ← (number) $2
Identified constant variable (byte*) SCREEN
Identified constant variable (byte*) SPRITE
Identified constant variable (byte*) YSIN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call call plexSetScreen (byte*) plexInit::screen
Inlined call call plexFreePrepare
Inlined call call plexFreeAdd (byte) plexShowSprite::ypos
Inlined call (byte~) plex_irq::$2 ← call plexFreeNextYpos
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [118] call plexSetScreen (byte*) plexInit::screen
Inlined call [153] call plexFreePrepare
Inlined call [159] call plexFreeAdd (byte) plexShowSprite::ypos
Inlined call [246] (byte~) plex_irq::$2 ← call plexFreeNextYpos
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -42,7 +42,7 @@ Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -47,8 +47,8 @@ Adding pointer type conversion cast (byte*) charset in (byte*) charset ← (numb
Adding pointer type conversion cast (byte*) tileset in (byte*) tileset ← (number) $2800
Adding pointer type conversion cast (byte*) colors in (byte*) colors ← (number) $d800
Adding pointer type conversion cast (byte*) level_address in (byte*) level_address ← (number) $3000
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte~) init::$3 ← call toD018 (byte*) screen (byte*) charset
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [409] (byte~) init::$3 ← call toD018 (byte*) screen (byte*) charset
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -1,10 +1,10 @@
Adding pointer type conversion cast (byte*) print_screen in (byte*) print_screen ← (number) $400
Inlined call (byte*~) init_points::$1 ← call getPoint (byte) init_points::i
Inlined call (byte*~) init_points::$2 ← call pointXpos (byte*) init_points::point
Inlined call (byte*~) init_points::$3 ← call pointYpos (byte*) init_points::point
Inlined call (byte*~) print_points::$2 ← call getPoint (byte) print_points::i
Inlined call (byte*~) print_points::$3 ← call pointXpos (byte*) print_points::point
Inlined call (byte*~) print_points::$6 ← call pointYpos (byte*) print_points::point
Inlined call [149] (byte*~) init_points::$1 ← call getPoint (byte) init_points::i
Inlined call [151] (byte*~) init_points::$2 ← call pointXpos (byte*) init_points::point
Inlined call [154] (byte*~) init_points::$3 ← call pointYpos (byte*) init_points::point
Inlined call [164] (byte*~) print_points::$2 ← call getPoint (byte) print_points::i
Inlined call [166] (byte*~) print_points::$3 ← call pointXpos (byte*) print_points::point
Inlined call [169] (byte*~) print_points::$6 ← call pointYpos (byte*) print_points::point
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) print_str::@4

@ -46,35 +46,35 @@ Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWA
Adding pointer type conversion cast (byte*) *(initEntry::$0) in *((byte**~) initEntry::$0) ← (number~) initEntry::$1
Adding pointer type conversion cast (byte*) *(initEntry::$2) in *((byte**~) initEntry::$2) ← (number~) initEntry::$3
Adding pointer type conversion cast (word*) *(initEntry::$6) in *((word**~) initEntry::$6) ← (number~) initEntry::$7
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call (byte*~) main::$1 ← call fileEntry (number) 1
Inlined call (byte*~) main::$2 ← call fileEntry (number) 2
Inlined call (byte**~) initEntry::$0 ← call entryBufDisk (byte*) initEntry::entry
Inlined call (byte**~) initEntry::$2 ← call entryBufEdit (byte*) initEntry::entry
Inlined call (word*~) initEntry::$4 ← call entryTsLen (byte*) initEntry::entry
Inlined call (word**~) initEntry::$6 ← call entryTsOrder (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$8 ← call entryTLastLink (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$10 ← call entrySLastLink (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$12 ← call entryBFlag (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$14 ← call entryBError (byte*) initEntry::entry
Inlined call (word*~) initEntry::$16 ← call entryUCross (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$18 ← call entryBAddrLo (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$20 ← call entryBAddrHi (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$22 ← call entryTHi (byte*) initEntry::entry
Inlined call (byte*~) initEntry::$24 ← call entryTLo (byte*) initEntry::entry
Inlined call (byte**~) printEntry::$1 ← call entryBufDisk (byte*) printEntry::entry
Inlined call (byte**~) printEntry::$6 ← call entryBufEdit (byte*) printEntry::entry
Inlined call (word*~) printEntry::$11 ← call entryTsLen (byte*) printEntry::entry
Inlined call (word**~) printEntry::$15 ← call entryTsOrder (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$20 ← call entryTLastLink (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$24 ← call entrySLastLink (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$28 ← call entryBFlag (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$32 ← call entryBError (byte*) printEntry::entry
Inlined call (word*~) printEntry::$36 ← call entryUCross (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$40 ← call entryBAddrLo (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$44 ← call entryBAddrHi (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$48 ← call entryTHi (byte*) printEntry::entry
Inlined call (byte*~) printEntry::$52 ← call entryTLo (byte*) printEntry::entry
Inlined call [327] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [577] (byte*~) main::$1 ← call fileEntry (number) 1
Inlined call [579] (byte*~) main::$2 ← call fileEntry (number) 2
Inlined call [605] (byte**~) initEntry::$0 ← call entryBufDisk (byte*) initEntry::entry
Inlined call [608] (byte**~) initEntry::$2 ← call entryBufEdit (byte*) initEntry::entry
Inlined call [611] (word*~) initEntry::$4 ← call entryTsLen (byte*) initEntry::entry
Inlined call [614] (word**~) initEntry::$6 ← call entryTsOrder (byte*) initEntry::entry
Inlined call [617] (byte*~) initEntry::$8 ← call entryTLastLink (byte*) initEntry::entry
Inlined call [620] (byte*~) initEntry::$10 ← call entrySLastLink (byte*) initEntry::entry
Inlined call [623] (byte*~) initEntry::$12 ← call entryBFlag (byte*) initEntry::entry
Inlined call [626] (byte*~) initEntry::$14 ← call entryBError (byte*) initEntry::entry
Inlined call [629] (word*~) initEntry::$16 ← call entryUCross (byte*) initEntry::entry
Inlined call [632] (byte*~) initEntry::$18 ← call entryBAddrLo (byte*) initEntry::entry
Inlined call [635] (byte*~) initEntry::$20 ← call entryBAddrHi (byte*) initEntry::entry
Inlined call [638] (byte*~) initEntry::$22 ← call entryTHi (byte*) initEntry::entry
Inlined call [641] (byte*~) initEntry::$24 ← call entryTLo (byte*) initEntry::entry
Inlined call [646] (byte**~) printEntry::$1 ← call entryBufDisk (byte*) printEntry::entry
Inlined call [651] (byte**~) printEntry::$6 ← call entryBufEdit (byte*) printEntry::entry
Inlined call [656] (word*~) printEntry::$11 ← call entryTsLen (byte*) printEntry::entry
Inlined call [660] (word**~) printEntry::$15 ← call entryTsOrder (byte*) printEntry::entry
Inlined call [665] (byte*~) printEntry::$20 ← call entryTLastLink (byte*) printEntry::entry
Inlined call [669] (byte*~) printEntry::$24 ← call entrySLastLink (byte*) printEntry::entry
Inlined call [673] (byte*~) printEntry::$28 ← call entryBFlag (byte*) printEntry::entry
Inlined call [677] (byte*~) printEntry::$32 ← call entryBError (byte*) printEntry::entry
Inlined call [681] (word*~) printEntry::$36 ← call entryUCross (byte*) printEntry::entry
Inlined call [685] (byte*~) printEntry::$40 ← call entryBAddrLo (byte*) printEntry::entry
Inlined call [689] (byte*~) printEntry::$44 ← call entryBAddrHi (byte*) printEntry::entry
Inlined call [693] (byte*~) printEntry::$48 ← call entryTHi (byte*) printEntry::entry
Inlined call [697] (byte*~) printEntry::$52 ← call entryTLo (byte*) printEntry::entry
Culled Empty Block (label) mul8u::@5
Culled Empty Block (label) mul8u::@6
Culled Empty Block (label) mul8u::@8

@ -44,7 +44,7 @@ Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_I
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
Adding pointer type conversion cast (byte*) SPRITE in (byte*) SPRITE ← (number) $2000
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -234,7 +234,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Minimal struct - different instances and copying
// Minimal struct - two instances being copied (using assignment)
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -296,7 +296,7 @@ Uplifting [] best 45 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Minimal struct - different instances and copying
// Minimal struct - two instances being copied (using assignment)
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -385,7 +385,7 @@ FINAL ASSEMBLER
Score: 30
//SEG0 File Comments
// Minimal struct - different instances and copying
// Minimal struct - two instances being copied (using assignment)
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

@ -8,25 +8,9 @@
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
[6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1
[7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2
[8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4
[9] *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$6) ← (byte~) main::$8
[10] (byte) main::i#1 ← ++ (byte) main::i#2
[11] if((byte) main::i#1!=(byte) 4) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1 main::@2
[12] (byte) main::i1#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::i1#1 )
[13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1
[14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17)
[15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17)
[16] (byte) main::i1#1 ← ++ (byte) main::i1#2
[17] if((byte) main::i1#1!=(byte) 4) goto main::@2
[4] *((const byte*) main::SCREEN#0) ← (const byte) main::x#0
[5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0
to:main::@return
main::@return: scope:[main] from main::@2
[18] return
main::@return: scope:[main] from main
[6] return
to:@return

@ -1,55 +1,28 @@
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
Replacing struct member reference (struct Point) main::p.x with member variable reference (byte) main::p_x
Replacing struct member reference (struct Point) main::p.y with member variable reference (byte) main::p_y
Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400
Culled Empty Block (label) main::@4
Identified constant variable (byte) main::x
Identified constant variable (byte) main::y
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(struct Point[4]) points#0 ← { fill( 4, 0) }
(byte) SIZEOF_POINT#0 ← (number) 2
(byte) OFFS_X#0 ← (number) 0
(byte) OFFS_Y#0 ← (number) 1
to:@1
main: scope:[main] from @1
(byte) main::i#0 ← (byte) 0
to:main::@1
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::$0 ← ((byte*)) (struct Point[4]) points#0
(byte*~) main::$1 ← (byte*~) main::$0 + (byte) OFFS_X#0
(byte~) main::$2 ← (byte) main::i#2 * (byte) SIZEOF_POINT#0
(byte*~) main::$3 ← (byte*~) main::$1 + (byte~) main::$2
*((byte*~) main::$3) ← (byte) main::i#2
(byte*~) main::$4 ← ((byte*)) (struct Point[4]) points#0
(byte*~) main::$5 ← (byte*~) main::$4 + (byte) OFFS_Y#0
(byte~) main::$6 ← (byte) main::i#2 * (byte) SIZEOF_POINT#0
(byte*~) main::$7 ← (byte*~) main::$5 + (byte~) main::$6
(number~) main::$8 ← (byte) main::i#2 + (number) 4
*((byte*~) main::$7) ← (number~) main::$8
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,3)
(bool~) main::$9 ← (byte) main::i#1 != rangelast(0,3)
if((bool~) main::$9) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1
(byte) main::x#0 ← (number) 2
(byte) main::y#0 ← (number) 3
(number~) main::$0 ← (byte) main::y#0 + (number) 1
(byte) main::p_x#0 ← (byte) main::x#0
(byte) main::p_y#0 ← (number~) main::$0
(byte*) main::SCREEN#0 ← ((byte*)) (number) $400
(byte) main::i1#0 ← (byte) 0
to:main::@3
main::@3: scope:[main] from main::@2 main::@3
(byte) main::i1#2 ← phi( main::@2/(byte) main::i1#0 main::@3/(byte) main::i1#1 )
(byte*~) main::$10 ← ((byte*)) (struct Point[4]) points#0
(byte*~) main::$11 ← (byte*~) main::$10 + (byte) OFFS_X#0
(byte~) main::$12 ← (byte) main::i1#2 * (byte) SIZEOF_POINT#0
(byte*~) main::$13 ← (byte*~) main::$11 + (byte~) main::$12
*((byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*~) main::$13)
(byte*~) main::$14 ← (byte*) main::SCREEN#0 + (number) $28
(byte*~) main::$15 ← ((byte*)) (struct Point[4]) points#0
(byte*~) main::$16 ← (byte*~) main::$15 + (byte) OFFS_Y#0
(byte~) main::$17 ← (byte) main::i1#2 * (byte) SIZEOF_POINT#0
(byte*~) main::$18 ← (byte*~) main::$16 + (byte~) main::$17
*((byte*~) main::$14 + (byte) main::i1#2) ← *((byte*~) main::$18)
(byte) main::i1#1 ← (byte) main::i1#2 + rangenext(0,3)
(bool~) main::$19 ← (byte) main::i1#1 != rangelast(0,3)
if((bool~) main::$19) goto main::@3
*((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::p_x#0
*((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::p_y#0
to:main::@return
main::@return: scope:[main] from main::@3
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
@ -64,190 +37,76 @@ SYMBOL TABLE SSA
(label) @2
(label) @begin
(label) @end
(byte) OFFS_X
(byte) OFFS_X#0
(byte) OFFS_Y
(byte) OFFS_Y#0
(byte) Point::x
(byte) Point::y
(byte) SIZEOF_POINT
(byte) SIZEOF_POINT#0
(void()) main()
(byte*~) main::$0
(byte*~) main::$1
(byte*~) main::$10
(byte*~) main::$11
(byte~) main::$12
(byte*~) main::$13
(byte*~) main::$14
(byte*~) main::$15
(byte*~) main::$16
(byte~) main::$17
(byte*~) main::$18
(bool~) main::$19
(byte~) main::$2
(byte*~) main::$3
(byte*~) main::$4
(byte*~) main::$5
(byte~) main::$6
(byte*~) main::$7
(number~) main::$8
(bool~) main::$9
(label) main::@1
(label) main::@2
(label) main::@3
(number~) main::$0
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i1
(byte) main::i1#0
(byte) main::i1#1
(byte) main::i1#2
(struct Point[4]) points
(struct Point[4]) points#0
(struct Point) main::p
(byte) main::p_x
(byte) main::p_x#0
(byte) main::p_y
(byte) main::p_y#0
(byte) main::x
(byte) main::x#0
(byte) main::y
(byte) main::y#0
Adding number conversion cast (unumber) 2 in (byte) SIZEOF_POINT#0 ← (number) 2
Adding number conversion cast (unumber) 0 in (byte) OFFS_X#0 ← (number) 0
Adding number conversion cast (unumber) 1 in (byte) OFFS_Y#0 ← (number) 1
Adding number conversion cast (unumber) 4 in (number~) main::$8 ← (byte) main::i#2 + (number) 4
Adding number conversion cast (unumber) main::$8 in (number~) main::$8 ← (byte) main::i#2 + (unumber)(number) 4
Adding number conversion cast (unumber) $28 in (byte*~) main::$14 ← (byte*) main::SCREEN#0 + (number) $28
Adding number conversion cast (unumber) 2 in (byte) main::x#0 ← (number) 2
Adding number conversion cast (unumber) 3 in (byte) main::y#0 ← (number) 3
Adding number conversion cast (unumber) 1 in (number~) main::$0 ← (byte) main::y#0 + (number) 1
Adding number conversion cast (unumber) main::$0 in (number~) main::$0 ← (byte) main::y#0 + (unumber)(number) 1
Adding number conversion cast (unumber) 0 in *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::p_x#0
Adding number conversion cast (unumber) 1 in *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::p_y#0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) SIZEOF_POINT#0 ← (unumber)(number) 2
Inlining cast (byte) OFFS_X#0 ← (unumber)(number) 0
Inlining cast (byte) OFFS_Y#0 ← (unumber)(number) 1
Inlining cast (byte*~) main::$0 ← (byte*)(struct Point[4]) points#0
Inlining cast (byte*~) main::$4 ← (byte*)(struct Point[4]) points#0
Inlining cast (byte) main::x#0 ← (unumber)(number) 2
Inlining cast (byte) main::y#0 ← (unumber)(number) 3
Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400
Inlining cast (byte*~) main::$10 ← (byte*)(struct Point[4]) points#0
Inlining cast (byte*~) main::$15 ← (byte*)(struct Point[4]) points#0
Successful SSA optimization Pass2InlineCast
Simplifying constant integer cast 2
Simplifying constant integer cast 3
Simplifying constant integer cast 1
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Simplifying constant integer cast 4
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $28
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 4
Finalized unsigned number type (byte) $28
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in (unumber~) main::$8 ← (byte) main::i#2 + (byte) 4
Identified duplicate assignment right side [13] (byte~) main::$6 ← (byte) main::i#2 * (byte) SIZEOF_POINT#0
Identified duplicate assignment right side [31] (byte~) main::$17 ← (byte) main::i1#2 * (byte) SIZEOF_POINT#0
Successful SSA optimization Pass2DuplicateRValueIdentification
Simple Condition (bool~) main::$9 [19] if((byte) main::i#1!=rangelast(0,3)) goto main::@1
Simple Condition (bool~) main::$19 [36] if((byte) main::i1#1!=rangelast(0,3)) goto main::@3
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant right-side identified [0] (struct Point[4]) points#0 ← { fill( 4, 0) }
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const struct Point[4]) points#0 = { fill( 4, 0) }
Constant (const byte) SIZEOF_POINT#0 = 2
Constant (const byte) OFFS_X#0 = 0
Constant (const byte) OFFS_Y#0 = 1
Constant (const byte) main::i#0 = 0
Constant (const byte*) main::SCREEN#0 = (byte*) 1024
Constant (const byte) main::i1#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (byte*)points#0 in [6] (byte*~) main::$0 ← (byte*)(const struct Point[4]) points#0
Constant value identified (byte*)points#0 in [11] (byte*~) main::$4 ← (byte*)(const struct Point[4]) points#0
Constant value identified (byte*)points#0 in [23] (byte*~) main::$10 ← (byte*)(const struct Point[4]) points#0
Constant value identified (byte*)points#0 in [29] (byte*~) main::$15 ← (byte*)(const struct Point[4]) points#0
Successful SSA optimization Pass2ConstantValues
Resolved ranged next value [17] main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value [19] if(main::i#1!=rangelast(0,3)) goto main::@1 to (number) 4
Resolved ranged next value [34] main::i1#1 ← ++ main::i1#2 to ++
Resolved ranged comparison value [36] if(main::i1#1!=rangelast(0,3)) goto main::@3 to (number) 4
Converting *(pointer+n) to pointer[n] [10] *((byte*~) main::$3) ← (byte) main::i#2 -- *(main::$1 + main::$2)
Converting *(pointer+n) to pointer[n] [16] *((byte*~) main::$7) ← (byte~) main::$8 -- *(main::$5 + main::$6)
Converting *(pointer+n) to pointer[n] [27] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*~) main::$13) -- *(main::$11 + main::$12)
Converting *(pointer+n) to pointer[n] [33] *((byte*~) main::$14 + (byte) main::i1#2) ← *((byte*~) main::$18) -- *(main::$16 + main::$17)
Successful SSA optimization Pass2InlineDerefIdx
Simplifying expression containing zero main::$0 in [7] (byte*~) main::$1 ← (byte*~) main::$0 + (const byte) OFFS_X#0
Simplifying expression containing zero main::$10 in [24] (byte*~) main::$11 ← (byte*~) main::$10 + (const byte) OFFS_X#0
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (byte*~) main::$3 and assignment [4] (byte*~) main::$3 ← (byte*~) main::$1 + (byte~) main::$2
Eliminating unused variable (byte*~) main::$7 and assignment [9] (byte*~) main::$7 ← (byte*~) main::$5 + (byte~) main::$6
Eliminating unused variable (byte*~) main::$13 and assignment [18] (byte*~) main::$13 ← (byte*~) main::$11 + (byte~) main::$12
Eliminating unused variable (byte*~) main::$18 and assignment [24] (byte*~) main::$18 ← (byte*~) main::$16 + (byte~) main::$17
Eliminating unused constant (const byte) OFFS_X#0
Successful SSA optimization PassNEliminateUnusedVars
Adding number conversion cast (unumber) 4 in if((byte) main::i#1!=(number) 4) goto main::@1
Adding number conversion cast (unumber) 4 in if((byte) main::i1#1!=(number) 4) goto main::@3
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 4
Simplifying constant integer cast 4
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 4
Finalized unsigned number type (byte) 4
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte*~) main::$1 = (byte*~) main::$0
Alias (byte~) main::$6 = (byte~) main::$2
Alias (byte*~) main::$11 = (byte*~) main::$10
Alias (byte~) main::$17 = (byte~) main::$12
Inferred type updated to byte in (unumber~) main::$0 ← (byte) main::y#0 + (byte) 1
Alias (byte) main::x#0 = (byte) main::p_x#0
Alias (byte) main::p_y#0 = (byte~) main::$0
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [17] (byte*~) main::$14 ← (const byte*) main::SCREEN#0 + (byte) $28
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$1 = (byte*)points#0
Constant (const byte*) main::$4 = (byte*)points#0
Constant (const byte*) main::$11 = (byte*)points#0
Constant (const byte*) main::$14 = main::SCREEN#0+$28
Constant (const byte*) main::$15 = (byte*)points#0
Constant (const byte) main::x#0 = 2
Constant (const byte) main::y#0 = 3
Constant (const byte*) main::SCREEN#0 = (byte*) 1024
Successful SSA optimization Pass2ConstantIdentification
Constant right-side identified [3] (byte*~) main::$5 ← (const byte*) main::$4 + (const byte) OFFS_Y#0
Constant right-side identified [11] (byte*~) main::$16 ← (const byte*) main::$15 + (const byte) OFFS_Y#0
Simplifying expression containing zero main::SCREEN#0 in [6] *((const byte*) main::SCREEN#0 + (byte) 0) ← (const byte) main::x#0
Successful SSA optimization PassNSimplifyExpressionWithZero
Constant right-side identified [0] (byte) main::p_y#0 ← (const byte) main::y#0 + (byte) 1
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$5 = main::$4+OFFS_Y#0
Constant (const byte*) main::$16 = main::$15+OFFS_Y#0
Constant (const byte) main::p_y#0 = main::y#0+1
Successful SSA optimization Pass2ConstantIdentification
Rewriting multiplication to use shift [1] (byte~) main::$6 ← (byte) main::i#2 * (const byte) SIZEOF_POINT#0
Rewriting multiplication to use shift [8] (byte~) main::$17 ← (byte) main::i1#2 * (const byte) SIZEOF_POINT#0
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings (const byte) main::i#0
Inlining constant with var siblings (const byte) main::i1#0
Constant inlined main::$1 = (byte*)(const struct Point[4]) points#0
Constant inlined main::$16 = (byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0
Constant inlined main::$5 = (byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0
Constant inlined main::i#0 = (byte) 0
Constant inlined main::i1#0 = (byte) 0
Constant inlined main::$14 = (const byte*) main::SCREEN#0+(byte) $28
Constant inlined main::$4 = (byte*)(const struct Point[4]) points#0
Constant inlined main::$15 = (byte*)(const struct Point[4]) points#0
Constant inlined main::$11 = (byte*)(const struct Point[4]) points#0
Successful SSA optimization Pass2ConstantInlining
Eliminating unused constant (const byte) SIZEOF_POINT#0
Successful SSA optimization PassNEliminateUnusedVars
Added new block during phi lifting main::@5(between main::@1 and main::@1)
Added new block during phi lifting main::@6(between main::@3 and main::@3)
Consolidated array index constant in *(main::SCREEN#0+1)
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
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [] to main:2
Created 2 initial phi equivalence classes
Coalesced [21] main::i1#3 ← main::i1#1
Coalesced [22] main::i#3 ← main::i#1
Coalesced down to 2 phi equivalence classes
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2
Culled Empty Block (label) main::@2
Culled Empty Block (label) main::@6
Culled Empty Block (label) main::@5
Renumbering block main::@3 to main::@2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
@ -260,76 +119,36 @@ FINAL CONTROL FLOW GRAPH
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
[6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1
[7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2
[8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4
[9] *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$6) ← (byte~) main::$8
[10] (byte) main::i#1 ← ++ (byte) main::i#2
[11] if((byte) main::i#1!=(byte) 4) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1 main::@2
[12] (byte) main::i1#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::i1#1 )
[13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1
[14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17)
[15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17)
[16] (byte) main::i1#1 ← ++ (byte) main::i1#2
[17] if((byte) main::i1#1!=(byte) 4) goto main::@2
[4] *((const byte*) main::SCREEN#0) ← (const byte) main::x#0
[5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0
to:main::@return
main::@return: scope:[main] from main::@2
[18] return
main::@return: scope:[main] from main
[6] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte) OFFS_X
(byte) OFFS_Y
(byte) Point::x
(byte) Point::y
(byte) SIZEOF_POINT
(void()) main()
(byte~) main::$17 16.5
(byte~) main::$6 11.0
(byte~) main::$8 22.0
(byte*) main::SCREEN
(byte) main::i
(byte) main::i#1 16.5
(byte) main::i#2 11.0
(byte) main::i1
(byte) main::i1#1 16.5
(byte) main::i1#2 13.75
(struct Point[4]) points
(struct Point) main::p
(byte) main::p_x
(byte) main::p_y
(byte) main::x
(byte) main::y
Initial phi equivalence classes
[ main::i#2 main::i#1 ]
[ main::i1#2 main::i1#1 ]
Added variable main::$6 to zero page equivalence class [ main::$6 ]
Added variable main::$8 to zero page equivalence class [ main::$8 ]
Added variable main::$17 to zero page equivalence class [ main::$17 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ main::i1#2 main::i1#1 ]
[ main::$6 ]
[ main::$8 ]
[ main::$17 ]
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Allocated zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ]
Allocated zp ZP_BYTE:4 [ main::$6 ]
Allocated zp ZP_BYTE:5 [ main::$8 ]
Allocated zp ZP_BYTE:6 [ main::$17 ]
INITIAL ASM
//SEG0 File Comments
// Minimal struct - array of struct - near pointer math indexing
// Minimal struct - initializing using a value list
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.const OFFS_Y = 1
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
@ -338,142 +157,52 @@ b1_from_bbegin:
//SEG5 @1
b1:
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG9 @end
//SEG8 @end
bend:
//SEG10 main
//SEG9 main
main: {
.const x = 2
.const y = 3
.label SCREEN = $400
.label _6 = 4
.label _8 = 5
.label _17 = 6
.label i = 2
.label i1 = 3
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta i
jmp b1
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
jmp b1
//SEG15 main::@1
b1:
//SEG16 [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1 -- vbuz1=vbuz2_rol_1
lda i
asl
sta _6
//SEG17 [7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz2
lda i
ldy _6
sta points,y
//SEG18 [8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4 -- vbuz1=vbuz2_plus_vbuc1
lax i
axs #-[4]
stx _8
//SEG19 [9] *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$6) ← (byte~) main::$8 -- pbuc1_derefidx_vbuz1=vbuz2
// points[i].x = i;
lda _8
ldy _6
sta points+OFFS_Y,y
//SEG20 [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [11] if((byte) main::i#1!=(byte) 4) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #4
cmp i
bne b1_from_b1
//SEG22 [12] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
b2_from_b1:
//SEG23 [12] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1
lda #0
sta i1
jmp b2
//SEG24 [12] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
b2_from_b2:
//SEG25 [12] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy
jmp b2
//SEG26 main::@2
b2:
//SEG27 [13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1 -- vbuz1=vbuz2_rol_1
lda i1
asl
sta _17
//SEG28 [14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2
ldy _17
lda points,y
ldy i1
sta SCREEN,y
//SEG29 [15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2
// SCREEN[i] = points[i].x;
ldy _17
lda points+OFFS_Y,y
ldy i1
sta SCREEN+$28,y
//SEG30 [16] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuz1=_inc_vbuz1
inc i1
//SEG31 [17] if((byte) main::i1#1!=(byte) 4) goto main::@2 -- vbuz1_neq_vbuc1_then_la1
lda #4
cmp i1
bne b2_from_b2
.const p_y = y+1
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::x#0 -- _deref_pbuc1=vbuc2
lda #x
sta SCREEN
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 -- _deref_pbuc1=vbuc2
lda #p_y
sta SCREEN+1
jmp breturn
//SEG32 main::@return
//SEG12 main::@return
breturn:
//SEG33 [18] return
//SEG13 [6] return
rts
}
points: .fill 2*4, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1 [ main::i#2 main::$6 ] ( main:2 [ main::i#2 main::$6 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Statement [7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2 [ main::i#2 main::$6 ] ( main:2 [ main::i#2 main::$6 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::$6 ]
Statement [8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4 [ main::i#2 main::$6 main::$8 ] ( main:2 [ main::i#2 main::$6 main::$8 ] ) always clobbers reg byte a
Statement [13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1 [ main::i1#2 main::$17 ] ( main:2 [ main::i1#2 main::$17 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ]
Statement [14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17) [ main::i1#2 main::$17 ] ( main:2 [ main::i1#2 main::$17 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ main::$17 ]
Statement [15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17) [ main::i1#2 ] ( main:2 [ main::i1#2 ] ) always clobbers reg byte a
Statement [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1 [ main::i#2 main::$6 ] ( main:2 [ main::i#2 main::$6 ] ) always clobbers reg byte a
Statement [7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2 [ main::i#2 main::$6 ] ( main:2 [ main::i#2 main::$6 ] ) always clobbers reg byte a
Statement [8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4 [ main::i#2 main::$6 main::$8 ] ( main:2 [ main::i#2 main::$6 main::$8 ] ) always clobbers reg byte a
Statement [13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1 [ main::i1#2 main::$17 ] ( main:2 [ main::i1#2 main::$17 ] ) always clobbers reg byte a
Statement [14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17) [ main::i1#2 main::$17 ] ( main:2 [ main::i1#2 main::$17 ] ) always clobbers reg byte a
Statement [15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17) [ main::i1#2 ] ( main:2 [ main::i1#2 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:4 [ main::$6 ] : zp ZP_BYTE:4 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:5 [ main::$8 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:6 [ main::$17 ] : zp ZP_BYTE:6 , reg byte x , reg byte y ,
Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) main::x#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main] 30.25: zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:5 [ main::$8 ] 16.5: zp ZP_BYTE:6 [ main::$17 ] 11: zp ZP_BYTE:4 [ main::$6 ]
Uplift Scope [Point]
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 898 combination reg byte y [ main::i1#2 main::i1#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$8 ] reg byte x [ main::$17 ] zp ZP_BYTE:4 [ main::$6 ]
Limited combination testing to 100 combinations of 324 possible.
Uplifting [Point] best 898 combination
Uplifting [] best 898 combination
Attempting to uplift remaining variables inzp ZP_BYTE:4 [ main::$6 ]
Uplifting [main] best 828 combination reg byte y [ main::$6 ]
Uplifting [Point] best 33 combination
Uplifting [main] best 33 combination
Uplifting [] best 33 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Minimal struct - array of struct - near pointer math indexing
// Minimal struct - initializing using a value list
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.const OFFS_Y = 1
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
@ -482,109 +211,46 @@ b1_from_bbegin:
//SEG5 @1
b1:
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG9 @end
//SEG8 @end
bend:
//SEG10 main
//SEG9 main
main: {
.const x = 2
.const y = 3
.label SCREEN = $400
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp b1
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
jmp b1
//SEG15 main::@1
b1:
//SEG16 [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1 -- vbuyy=vbuxx_rol_1
txa
asl
tay
//SEG17 [7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2 -- pbuc1_derefidx_vbuyy=vbuxx
txa
sta points,y
//SEG18 [8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4 -- vbuaa=vbuxx_plus_vbuc1
txa
clc
adc #4
//SEG19 [9] *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$6) ← (byte~) main::$8 -- pbuc1_derefidx_vbuyy=vbuaa
// points[i].x = i;
sta points+OFFS_Y,y
//SEG20 [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
inx
//SEG21 [11] if((byte) main::i#1!=(byte) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
cpx #4
bne b1_from_b1
//SEG22 [12] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
b2_from_b1:
//SEG23 [12] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1
ldy #0
jmp b2
//SEG24 [12] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
b2_from_b2:
//SEG25 [12] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy
jmp b2
//SEG26 main::@2
b2:
//SEG27 [13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1 -- vbuxx=vbuyy_rol_1
tya
asl
tax
//SEG28 [14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
lda points,x
sta SCREEN,y
//SEG29 [15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
// SCREEN[i] = points[i].x;
lda points+OFFS_Y,x
sta SCREEN+$28,y
//SEG30 [16] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuyy=_inc_vbuyy
iny
//SEG31 [17] if((byte) main::i1#1!=(byte) 4) goto main::@2 -- vbuyy_neq_vbuc1_then_la1
cpy #4
bne b2_from_b2
.const p_y = y+1
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::x#0 -- _deref_pbuc1=vbuc2
lda #x
sta SCREEN
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 -- _deref_pbuc1=vbuc2
lda #p_y
sta SCREEN+1
jmp breturn
//SEG32 main::@return
//SEG12 main::@return
breturn:
//SEG33 [18] return
//SEG13 [6] return
rts
}
points: .fill 2*4, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b1 with b1
Replacing label b2_from_b2 with b2
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_b1:
Removing instruction b2_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction b1_from_main:
Removing instruction b2_from_b1:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp b1
Removing instruction jmp b2
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
@ -592,110 +258,53 @@ FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte) OFFS_X
(byte) OFFS_Y
(const byte) OFFS_Y#0 OFFS_Y = (byte) 1
(byte) Point::x
(byte) Point::y
(byte) SIZEOF_POINT
(void()) main()
(byte~) main::$17 reg byte x 16.5
(byte~) main::$6 reg byte y 11.0
(byte~) main::$8 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024
(byte) main::i
(byte) main::i#1 reg byte x 16.5
(byte) main::i#2 reg byte x 11.0
(byte) main::i1
(byte) main::i1#1 reg byte y 16.5
(byte) main::i1#2 reg byte y 13.75
(struct Point[4]) points
(const struct Point[4]) points#0 points = { fill( 4, 0) }
(struct Point) main::p
(byte) main::p_x
(byte) main::p_y
(const byte) main::p_y#0 p_y = (const byte) main::y#0+(byte) 1
(byte) main::x
(const byte) main::x#0 x = (byte) 2
(byte) main::y
(const byte) main::y#0 y = (byte) 3
reg byte x [ main::i#2 main::i#1 ]
reg byte y [ main::i1#2 main::i1#1 ]
reg byte y [ main::$6 ]
reg byte a [ main::$8 ]
reg byte x [ main::$17 ]
FINAL ASSEMBLER
Score: 666
Score: 18
//SEG0 File Comments
// Minimal struct - array of struct - near pointer math indexing
// Minimal struct - initializing using a value list
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.const OFFS_Y = 1
//SEG3 @begin
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
//SEG5 @1
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG9 @end
//SEG10 main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
//SEG8 @end
//SEG9 main
main: {
.const x = 2
.const y = 3
.label SCREEN = $400
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
//SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG15 main::@1
b1:
//SEG16 [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 1 -- vbuyy=vbuxx_rol_1
txa
asl
tay
//SEG17 [7] *((byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (byte) main::i#2 -- pbuc1_derefidx_vbuyy=vbuxx
txa
sta points,y
//SEG18 [8] (byte~) main::$8 ← (byte) main::i#2 + (byte) 4 -- vbuaa=vbuxx_plus_vbuc1
txa
clc
adc #4
//SEG19 [9] *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$6) ← (byte~) main::$8 -- pbuc1_derefidx_vbuyy=vbuaa
// points[i].x = i;
sta points+OFFS_Y,y
//SEG20 [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
inx
//SEG21 [11] if((byte) main::i#1!=(byte) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
cpx #4
bne b1
//SEG22 [12] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
//SEG23 [12] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1
ldy #0
//SEG24 [12] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
//SEG25 [12] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy
//SEG26 main::@2
b2:
//SEG27 [13] (byte~) main::$17 ← (byte) main::i1#2 << (byte) 1 -- vbuxx=vbuyy_rol_1
tya
asl
tax
//SEG28 [14] *((const byte*) main::SCREEN#0 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0 + (byte~) main::$17) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
lda points,x
sta SCREEN,y
//SEG29 [15] *((const byte*) main::SCREEN#0+(byte) $28 + (byte) main::i1#2) ← *((byte*)(const struct Point[4]) points#0+(const byte) OFFS_Y#0 + (byte~) main::$17) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
// SCREEN[i] = points[i].x;
lda points+OFFS_Y,x
sta SCREEN+$28,y
//SEG30 [16] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuyy=_inc_vbuyy
iny
//SEG31 [17] if((byte) main::i1#1!=(byte) 4) goto main::@2 -- vbuyy_neq_vbuc1_then_la1
cpy #4
bne b2
//SEG32 main::@return
//SEG33 [18] return
.const p_y = y+1
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::x#0 -- _deref_pbuc1=vbuc2
lda #x
sta SCREEN
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 -- _deref_pbuc1=vbuc2
lda #p_y
sta SCREEN+1
//SEG12 main::@return
//SEG13 [6] return
rts
}
points: .fill 2*4, 0

17
src/test/ref/struct-6.asm Normal file

@ -0,0 +1,17 @@
// Minimal struct - nesting structs
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
.const p_x = $a
.const p_y = $a
.const c_radius = 5
.label SCREEN = $400
lda #p_x
sta SCREEN
lda #p_y
sta SCREEN+1
lda #c_radius
sta SCREEN+2
rts
}

17
src/test/ref/struct-6.cfg Normal file

@ -0,0 +1,17 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] *((const byte*) main::SCREEN#0) ← (const byte) main::p_x#0
[5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0
[6] *((const byte*) main::SCREEN#0+(byte) 2) ← (const byte) main::c_radius#0
to:main::@return
main::@return: scope:[main] from main
[7] return
to:@return

353
src/test/ref/struct-6.log Normal file

@ -0,0 +1,353 @@
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
Created struct value member variable (struct Point) main::c_center
Created struct value member variable (byte) main::c_radius
Converted struct value to member variables (struct Circle) main::c
Adding struct value list initializer (byte) main::p_x ← (number) $a
Adding struct value list initializer (byte) main::p_y ← (number) $a
Adding struct value list initializer (struct Point) main::c_center ← (struct Point) main::p
Adding struct value list initializer (byte) main::c_radius ← (number) 5
Replacing struct member reference (struct Circle) main::c.center with member variable reference (struct Point) main::c_center
Replacing struct member reference (struct Circle) main::c.center with member variable reference (struct Point) main::c_center
Replacing struct member reference (struct Circle) main::c.radius with member variable reference (byte) main::c_radius
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 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 variable reference (byte) main::c_center_x
Replacing struct member reference (struct Point) main::c_center.y with member variable reference (byte) main::c_center_y
Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400
Identified constant variable (byte) main::p_x
Identified constant variable (byte) main::p_y
Identified constant variable (byte) main::c_radius
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
main: scope:[main] from @1
(byte) main::p_x#0 ← (number) $a
(byte) main::p_y#0 ← (number) $a
(byte) main::c_center_x#0 ← (byte) main::p_x#0
(byte) main::c_center_y#0 ← (byte) main::p_y#0
(byte) main::c_radius#0 ← (number) 5
(byte*) main::SCREEN#0 ← ((byte*)) (number) $400
*((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::c_center_x#0
*((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::c_center_y#0
*((byte*) main::SCREEN#0 + (number) 2) ← (byte) main::c_radius#0
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
(label) @1
(label) @2
(label) @begin
(label) @end
(struct Point) Circle::center
(byte) Circle::radius
(byte) Point::x
(byte) Point::y
(void()) main()
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(struct Circle) main::c
(struct Point) main::c_center
(byte) main::c_center_x
(byte) main::c_center_x#0
(byte) main::c_center_y
(byte) main::c_center_y#0
(byte) main::c_radius
(byte) main::c_radius#0
(struct Point) main::p
(byte) main::p_x
(byte) main::p_x#0
(byte) main::p_y
(byte) main::p_y#0
Adding number conversion cast (unumber) $a in (byte) main::p_x#0 ← (number) $a
Adding number conversion cast (unumber) $a in (byte) main::p_y#0 ← (number) $a
Adding number conversion cast (unumber) 5 in (byte) main::c_radius#0 ← (number) 5
Adding number conversion cast (unumber) 0 in *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::c_center_x#0
Adding number conversion cast (unumber) 1 in *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::c_center_y#0
Adding number conversion cast (unumber) 2 in *((byte*) main::SCREEN#0 + (number) 2) ← (byte) main::c_radius#0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) main::p_x#0 ← (unumber)(number) $a
Inlining cast (byte) main::p_y#0 ← (unumber)(number) $a
Inlining cast (byte) main::c_radius#0 ← (unumber)(number) 5
Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400
Successful SSA optimization Pass2InlineCast
Simplifying constant integer cast $a
Simplifying constant integer cast $a
Simplifying constant integer cast 5
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $a
Finalized unsigned number type (byte) $a
Finalized unsigned number type (byte) 5
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) main::p_x#0 = (byte) main::c_center_x#0
Alias (byte) main::p_y#0 = (byte) main::c_center_y#0
Successful SSA optimization Pass2AliasElimination
Constant (const byte) main::p_x#0 = $a
Constant (const byte) main::p_y#0 = $a
Constant (const byte) main::c_radius#0 = 5
Constant (const byte*) main::SCREEN#0 = (byte*) 1024
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero main::SCREEN#0 in [6] *((const byte*) main::SCREEN#0 + (byte) 0) ← (const byte) main::p_x#0
Successful SSA optimization PassNSimplifyExpressionWithZero
Consolidated array index constant in *(main::SCREEN#0+1)
Consolidated array index constant in *(main::SCREEN#0+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()
main: scope:[main] from @1
[4] *((const byte*) main::SCREEN#0) ← (const byte) main::p_x#0
[5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0
[6] *((const byte*) main::SCREEN#0+(byte) 2) ← (const byte) main::c_radius#0
to:main::@return
main::@return: scope:[main] from main
[7] return
to:@return
VARIABLE REGISTER WEIGHTS
(struct Point) Circle::center
(byte) Circle::radius
(byte) Point::x
(byte) Point::y
(void()) main()
(byte*) main::SCREEN
(struct Circle) main::c
(struct Point) main::c_center
(byte) main::c_center_x
(byte) main::c_center_y
(byte) main::c_radius
(struct Point) main::p
(byte) main::p_x
(byte) main::p_y
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Minimal struct - nesting structs
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
jsr main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG8 @end
bend:
//SEG9 main
main: {
.const p_x = $a
.const p_y = $a
.const c_radius = 5
.label SCREEN = $400
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::p_x#0 -- _deref_pbuc1=vbuc2
lda #p_x
sta SCREEN
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 -- _deref_pbuc1=vbuc2
lda #p_y
sta SCREEN+1
//SEG12 [6] *((const byte*) main::SCREEN#0+(byte) 2) ← (const byte) main::c_radius#0 -- _deref_pbuc1=vbuc2
lda #c_radius
sta SCREEN+2
jmp breturn
//SEG13 main::@return
breturn:
//SEG14 [7] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) main::p_x#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) main::SCREEN#0+(byte) 2) ← (const byte) main::c_radius#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [Point]
Uplift Scope [Circle]
Uplift Scope [main]
Uplift Scope []
Uplifting [Point] best 39 combination
Uplifting [Circle] best 39 combination
Uplifting [main] best 39 combination
Uplifting [] best 39 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Minimal struct - nesting structs
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
jsr main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG8 @end
bend:
//SEG9 main
main: {
.const p_x = $a
.const p_y = $a
.const c_radius = 5
.label SCREEN = $400
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::p_x#0 -- _deref_pbuc1=vbuc2
lda #p_x
sta SCREEN
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 -- _deref_pbuc1=vbuc2
lda #p_y
sta SCREEN+1
//SEG12 [6] *((const byte*) main::SCREEN#0+(byte) 2) ← (const byte) main::c_radius#0 -- _deref_pbuc1=vbuc2
lda #c_radius
sta SCREEN+2
jmp breturn
//SEG13 main::@return
breturn:
//SEG14 [7] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction b1_from_bbegin:
Removing instruction b1:
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 bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(struct Point) Circle::center
(byte) Circle::radius
(byte) Point::x
(byte) Point::y
(void()) main()
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024
(struct Circle) main::c
(struct Point) main::c_center
(byte) main::c_center_x
(byte) main::c_center_y
(byte) main::c_radius
(const byte) main::c_radius#0 c_radius = (byte) 5
(struct Point) main::p
(byte) main::p_x
(const byte) main::p_x#0 p_x = (byte) $a
(byte) main::p_y
(const byte) main::p_y#0 p_y = (byte) $a
FINAL ASSEMBLER
Score: 24
//SEG0 File Comments
// Minimal struct - nesting structs
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//SEG3 @begin
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
//SEG5 @1
//SEG6 [2] call main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
//SEG8 @end
//SEG9 main
main: {
.const p_x = $a
.const p_y = $a
.const c_radius = 5
.label SCREEN = $400
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::p_x#0 -- _deref_pbuc1=vbuc2
lda #p_x
sta SCREEN
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::p_y#0 -- _deref_pbuc1=vbuc2
lda #p_y
sta SCREEN+1
//SEG12 [6] *((const byte*) main::SCREEN#0+(byte) 2) ← (const byte) main::c_radius#0 -- _deref_pbuc1=vbuc2
lda #c_radius
sta SCREEN+2
//SEG13 main::@return
//SEG14 [7] return
rts
}

@ -0,0 +1 @@
program

@ -45,7 +45,7 @@ Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTER
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) print_screen in (byte*) print_screen ← (number) $400
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -45,7 +45,7 @@ Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTER
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) print_screen in (byte*) print_screen ← (number) $400
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -42,7 +42,7 @@ Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -44,7 +44,7 @@ Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_I
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
Adding pointer type conversion cast (byte*) main::sc in (byte*) main::sc ← (number) $400
Adding pointer type conversion cast (byte*) main::screen in (byte*) main::screen ← (number) $400
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3

@ -9,7 +9,7 @@ Adding pointer type conversion cast (word*) mulf16u::memB in (word*) mulf16u::me
Adding pointer type conversion cast (dword*) mulf16u::memR in (dword*) mulf16u::memR ← (number) $fc
Adding pointer type conversion cast (byte*) BGCOL in (byte*) BGCOL ← (number) $d021
Identified constant variable (byte*) BGCOL
Inlined call call mulf8s_prepare (signed byte) mulf8s::a
Inlined call [319] call mulf8s_prepare (signed byte) mulf8s::a
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) print_str::@4

@ -11,7 +11,7 @@ Adding pointer type conversion cast (byte*) BGCOL in (byte*) BGCOL ← (number)
Adding pointer type conversion cast (byte*) mulf_init_asm::mem in (byte*) mulf_init_asm::mem ← (number) $ff
Identified constant variable (byte*) BGCOL
Identified constant variable (byte*) mulf_init_asm::mem
Inlined call call mulf8s_prepare (signed byte) mulf8s::a
Inlined call [319] call mulf8s_prepare (signed byte) mulf8s::a
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) print_str::@4