mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-03 12:07:26 +00:00
Eliminating redundant casts.
This commit is contained in:
parent
27444f7c7d
commit
d6427d58df
4
src/main/fragment/pbuz1=_deref_pptc1.asm
Normal file
4
src/main/fragment/pbuz1=_deref_pptc1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
lda {c1}+1
|
||||
sta {z1}+1
|
@ -247,6 +247,7 @@ public class Compiler {
|
||||
optimizations.add(new Pass2FixInlineConstructors(program));
|
||||
optimizations.add(new Pass2TypeInference(program));
|
||||
optimizations.add(new PassNEliminateUnusedVars(program));
|
||||
optimizations.add(new Pass2EliminateRedundantCasts(program));
|
||||
optimizations.add(new Pass2NopCastElimination(program));
|
||||
optimizations.add(new Pass2EliminateUnusedBlocks(program));
|
||||
optimizations.add(new Pass2RangeResolving(program));
|
||||
|
@ -0,0 +1,75 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.operators.OperatorCastPtr;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
||||
/**
|
||||
* Eliminate casts that are not necessary
|
||||
*/
|
||||
public class Pass2EliminateRedundantCasts extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2EliminateRedundantCasts(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
boolean modified = false;
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(isRedundantCast(assignment)) {
|
||||
// Redundant cast
|
||||
getLog().append("Removing redundant cast " + statement.toString(getProgram(), false));
|
||||
assignment.setOperator(null);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the assignment is a redundant cast
|
||||
*
|
||||
* @param assignment The assignment to examine
|
||||
* @return true if is is a redundant cast
|
||||
*/
|
||||
private boolean isRedundantCast(StatementAssignment assignment) {
|
||||
RValue rValue2 = assignment.getrValue2();
|
||||
SymbolType rValue2Type = SymbolTypeInference.inferType(getScope(), rValue2);
|
||||
if(Operators.CAST_BYTE.equals(assignment.getOperator()) && SymbolType.BYTE.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(Operators.CAST_SBYTE.equals(assignment.getOperator()) && SymbolType.SBYTE.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(Operators.CAST_WORD.equals(assignment.getOperator()) && SymbolType.WORD.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(Operators.CAST_SWORD.equals(assignment.getOperator()) && SymbolType.SWORD.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(Operators.CAST_DWORD.equals(assignment.getOperator()) && SymbolType.DWORD.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(Operators.CAST_SDWORD.equals(assignment.getOperator()) && SymbolType.SDWORD.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(Operators.CAST_BOOL.equals(assignment.getOperator()) && SymbolType.BOOLEAN.equals(rValue2Type)) {
|
||||
return true;
|
||||
} else if(assignment.getOperator() instanceof OperatorCastPtr) {
|
||||
// Casting to a pointer
|
||||
OperatorCastPtr operatorCastPtr = (OperatorCastPtr) assignment.getOperator();
|
||||
if(rValue2Type.equals(new SymbolTypePointer(operatorCastPtr.getElementType()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -149,6 +149,7 @@ public class Pass4CodeGeneration {
|
||||
|
||||
/**
|
||||
* Generate the end of a scope
|
||||
*
|
||||
* @param asm The assembler program being generated
|
||||
* @param currentScope The current scope, which is ending here
|
||||
*/
|
||||
@ -156,7 +157,7 @@ public class Pass4CodeGeneration {
|
||||
if(!ScopeRef.ROOT.equals(currentScope)) {
|
||||
// Generate any indirect calls pending
|
||||
for(String indirectCallAsmName : indirectCallAsmNames) {
|
||||
asm.addLabel("bi_"+indirectCallAsmName);
|
||||
asm.addLabel("bi_" + indirectCallAsmName);
|
||||
asm.addInstruction("jmp", AsmAddressingMode.IND, indirectCallAsmName, false);
|
||||
}
|
||||
indirectCallAsmNames = new ArrayList<>();
|
||||
@ -167,6 +168,7 @@ public class Pass4CodeGeneration {
|
||||
|
||||
/**
|
||||
* Add an indirect call to the assembler program. Also queues ASM for the indirect jump to be added at the end of the block.
|
||||
*
|
||||
* @param asm The ASM program being built
|
||||
* @param procedureVariable The variable containing the function pointer
|
||||
* @param codeScopeRef The scope containing the code being generated. Used for adding scope to the name when needed (eg. line.x1 when referencing x1 variable inside line scope from outside line scope).
|
||||
@ -178,9 +180,9 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate a comment that describes the procedure signature and parameter transfer
|
||||
*
|
||||
* @param asm The assembler program being generated
|
||||
* @param procedure The procedure
|
||||
*/
|
||||
@ -210,7 +212,7 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
}
|
||||
signature.append(")");
|
||||
if(i>0) {
|
||||
if(i > 0) {
|
||||
asm.addComment(signature.toString(), false);
|
||||
}
|
||||
}
|
||||
@ -395,15 +397,11 @@ public class Pass4CodeGeneration {
|
||||
asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmElements);
|
||||
added.add(asmName);
|
||||
} else if(elementType instanceof SymbolTypePointer) {
|
||||
if(((SymbolTypePointer) elementType).getElementType() instanceof SymbolTypeProcedure) {
|
||||
asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmElements);
|
||||
added.add(asmName);
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled constant array element type " + constantArrayList.toString(program));
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled constant array element type " + constantArrayList.toString(program));
|
||||
}
|
||||
} else if(constantVar.getValue() instanceof ConstantArrayFilled) {
|
||||
ConstantArrayFilled constantArrayFilled = (ConstantArrayFilled) constantVar.getValue();
|
||||
ConstantValue arraySize = constantArrayFilled.getSize();
|
||||
@ -493,7 +491,7 @@ public class Pass4CodeGeneration {
|
||||
try {
|
||||
generateStatementAsm(asm, block, statement, aluState, true);
|
||||
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
|
||||
throw new CompileError("Unknown fragment for statement " + statement.toString(program, false)+"\nMissing ASM fragment "+e.getFragmentSignature(), e);
|
||||
throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statement.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -585,7 +583,7 @@ public class Pass4CodeGeneration {
|
||||
asmFragmentInstance.generate(asm);
|
||||
AsmSegment currentSegment = asm.getCurrentSegment();
|
||||
|
||||
if(statementAsm.getDeclaredClobber()!=null) {
|
||||
if(statementAsm.getDeclaredClobber() != null) {
|
||||
currentSegment.setClobberOverwrite(statementAsm.getDeclaredClobber());
|
||||
} else {
|
||||
for(AsmLine asmLine : currentSegment.getLines()) {
|
||||
@ -634,7 +632,7 @@ public class Pass4CodeGeneration {
|
||||
if(procedureVariableType instanceof SymbolTypePointer) {
|
||||
if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) {
|
||||
String varAsmName = AsmFormat.getAsmParamName(procedureVariable, block.getScope());
|
||||
asm.addInstruction("jsr", AsmAddressingMode.ABS, varAsmName,false);
|
||||
asm.addInstruction("jsr", AsmAddressingMode.ABS, varAsmName, false);
|
||||
supported = true;
|
||||
}
|
||||
}
|
||||
@ -653,6 +651,7 @@ public class Pass4CodeGeneration {
|
||||
|
||||
/**
|
||||
* Generate ASM code for an ASM fragment instance
|
||||
*
|
||||
* @param asm The ASM program to generate into
|
||||
* @param asmFragmentInstanceSpecFactory The ASM fragment instance specification factory
|
||||
*/
|
||||
@ -661,7 +660,7 @@ public class Pass4CodeGeneration {
|
||||
AsmFragmentInstanceSpec asmFragmentInstanceSpec = asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec();
|
||||
AsmFragmentInstance asmFragmentInstance = null;
|
||||
StringBuffer fragmentVariationsTried = new StringBuffer();
|
||||
while(asmFragmentInstance==null) {
|
||||
while(asmFragmentInstance == null) {
|
||||
try {
|
||||
asmFragmentInstance = AsmFragmentTemplateSynthesizer.getFragmentInstance(asmFragmentInstanceSpec, program.getLog());
|
||||
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
|
||||
@ -671,11 +670,11 @@ public class Pass4CodeGeneration {
|
||||
if(asmFragmentInstanceSpec.hasNextVariation()) {
|
||||
asmFragmentInstanceSpec.nextVariation();
|
||||
if(program.getLog().isVerboseFragmentLog()) {
|
||||
program.getLog().append("Fragment not found "+signature+". Attempting another variation "+asmFragmentInstanceSpec.getSignature());
|
||||
program.getLog().append("Fragment not found " + signature + ". Attempting another variation " + asmFragmentInstanceSpec.getSignature());
|
||||
}
|
||||
} else {
|
||||
// No more variations available - fail with an error
|
||||
throw new AsmFragmentTemplateSynthesizer.UnknownFragmentException("Fragment not found "+initialSignature+". Attempted variations "+fragmentVariationsTried);
|
||||
throw new AsmFragmentTemplateSynthesizer.UnknownFragmentException("Fragment not found " + initialSignature + ". Attempted variations " + fragmentVariationsTried);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ public class TestPrograms {
|
||||
compileAndCompare("semi-struct-2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSemiStruct1() throws IOException, URISyntaxException {
|
||||
compileAndCompare("semi-struct-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReserveZpGlobal() throws IOException, URISyntaxException {
|
||||
compileAndCompare("reserve-zp-global");
|
||||
@ -507,6 +512,16 @@ public class TestPrograms {
|
||||
compileAndCompare("inline-asm-optimized");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCastNotNeeded2() throws IOException, URISyntaxException {
|
||||
compileAndCompare("cast-not-needed-2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCastNotNeeded3() throws IOException, URISyntaxException {
|
||||
compileAndCompare("cast-not-needed-3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCastNotNeeded() throws IOException, URISyntaxException {
|
||||
compileAndCompare("cast-not-needed");
|
||||
|
17
src/test/kc/cast-not-needed-2.kc
Normal file
17
src/test/kc/cast-not-needed-2.kc
Normal file
@ -0,0 +1,17 @@
|
||||
// Tests a cast that is not needed
|
||||
|
||||
byte*[] screens = { (byte*)$0400, (byte*)$1400 };
|
||||
|
||||
void main() {
|
||||
byte* screen;
|
||||
screen = getScreen(0);
|
||||
*spritePtr(screen) = $22;
|
||||
}
|
||||
|
||||
inline byte* getScreen(byte id) {
|
||||
return screens[id];
|
||||
}
|
||||
|
||||
inline byte* spritePtr(byte* screen) {
|
||||
return (byte*)(screen+$378);
|
||||
}
|
16
src/test/kc/cast-not-needed-3.kc
Normal file
16
src/test/kc/cast-not-needed-3.kc
Normal file
@ -0,0 +1,16 @@
|
||||
// Tests a cast that is not needed
|
||||
|
||||
byte*[] screens = { (byte*)$0400, (byte*)$1400 };
|
||||
|
||||
void main() {
|
||||
byte* DSP = $400;
|
||||
DSP[0] = spritePtr(getScreen(0));
|
||||
}
|
||||
|
||||
inline byte* getScreen(byte id) {
|
||||
return screens[id];
|
||||
}
|
||||
|
||||
inline byte spritePtr(byte* screen) {
|
||||
return (byte)*(screen+$378);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
//
|
||||
// Tests a cast that is not needed
|
||||
|
||||
byte* sprite = $5000;
|
||||
byte* SCREEN = $4400;
|
||||
|
64
src/test/kc/semi-struct-1.kc
Normal file
64
src/test/kc/semi-struct-1.kc
Normal file
@ -0,0 +1,64 @@
|
||||
// Implementing a semi-struct without the struct keyword by using pointer math and inline functions
|
||||
//
|
||||
// struct Point {
|
||||
// byte xpos; // The x-position
|
||||
// byte ypos; // The y-position
|
||||
// };
|
||||
// Point[NUM_POINTS] points;
|
||||
|
||||
import "print"
|
||||
|
||||
// The size of a point
|
||||
const byte SIZEOF_POINT = 2;
|
||||
|
||||
// The number of points
|
||||
const byte NUM_POINTS = 4;
|
||||
|
||||
// All points
|
||||
byte[NUM_POINTS*SIZEOF_POINT] points;
|
||||
|
||||
// Get a point by index
|
||||
inline byte* getPoint(byte idx) {
|
||||
return points+idx*SIZEOF_POINT;
|
||||
}
|
||||
|
||||
// Get x-position of the point
|
||||
inline byte* pointXpos(byte* point) {
|
||||
return (byte*)(point+0);
|
||||
}
|
||||
|
||||
// Get y-position of the point
|
||||
inline byte* pointYpos(byte* point) {
|
||||
return (byte*)(point+1);
|
||||
}
|
||||
|
||||
// Initialize some points and print them
|
||||
void main() {
|
||||
init_points();
|
||||
print_points();
|
||||
}
|
||||
|
||||
// Initialize points
|
||||
void init_points() {
|
||||
byte pos = 10;
|
||||
for(byte i: 0..NUM_POINTS-1) {
|
||||
byte* point = getPoint(i);
|
||||
*pointXpos(point) = pos;
|
||||
pos +=10;
|
||||
*pointYpos(point) = pos;
|
||||
pos +=10;
|
||||
}
|
||||
}
|
||||
|
||||
// Print points
|
||||
void print_points() {
|
||||
print_cls();
|
||||
for(byte i: 0..NUM_POINTS-1) {
|
||||
byte* point = getPoint(i);
|
||||
print_byte(*pointXpos(point));
|
||||
print_str(" ");
|
||||
print_byte(*pointYpos(point));
|
||||
print_ln();
|
||||
}
|
||||
}
|
||||
|
@ -23,17 +23,17 @@ import "print"
|
||||
import "keyboard"
|
||||
|
||||
// The size of a file ENTRY
|
||||
const byte ENTRY_SIZE = 18;
|
||||
const byte SIZEOF_ENTRY = 18;
|
||||
|
||||
// The maximal number of files
|
||||
const byte MAX_FILES = 144;
|
||||
|
||||
// All files
|
||||
byte[(word)MAX_FILES*ENTRY_SIZE] files;
|
||||
byte[(word)MAX_FILES*SIZEOF_ENTRY] files;
|
||||
|
||||
// Get pointer to a numbered file entry in the files-table
|
||||
inline byte* fileEntry(byte idx) {
|
||||
return files+mul8u(idx, ENTRY_SIZE);
|
||||
return files+mul8u(idx, SIZEOF_ENTRY);
|
||||
}
|
||||
|
||||
// Get file position in disk buffer.
|
||||
|
26
src/test/ref/cast-not-needed-2.asm
Normal file
26
src/test/ref/cast-not-needed-2.asm
Normal file
@ -0,0 +1,26 @@
|
||||
// Tests a cast that is not needed
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_POINTER = 2
|
||||
main: {
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1_return = 2
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
clc
|
||||
lda spritePtr1_return
|
||||
adc #<$378
|
||||
sta spritePtr1_return
|
||||
lda spritePtr1_return+1
|
||||
adc #>$378
|
||||
sta spritePtr1_return+1
|
||||
lda #$22
|
||||
ldy #0
|
||||
sta (spritePtr1_return),y
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
24
src/test/ref/cast-not-needed-2.cfg
Normal file
24
src/test/ref/cast-not-needed-2.cfg
Normal file
@ -0,0 +1,24 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::getScreen1
|
||||
main::getScreen1: scope:[main] from main
|
||||
[5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER)
|
||||
to:main::spritePtr1
|
||||
main::spritePtr1: scope:[main] from main::getScreen1
|
||||
[6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::spritePtr1
|
||||
[7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[8] return
|
||||
to:@return
|
439
src/test/ref/cast-not-needed-2.log
Normal file
439
src/test/ref/cast-not-needed-2.log
Normal file
@ -0,0 +1,439 @@
|
||||
Fixing pointer array-indexing *((byte*[]) screens + (byte) getScreen::id)
|
||||
Inlined call (byte*~) main::$0 ← call getScreen (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
Inlined call (byte*~) main::$1 ← call spritePtr (byte*) main::screen
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*~) $0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte*~) $1 ← ((byte*)) (word/signed word/dword/signed dword) $1400
|
||||
(byte*[]) screens#0 ← { (byte*~) $0, (byte*~) $1 }
|
||||
to:@3
|
||||
main: scope:[main] from @3
|
||||
(byte*) main::screen#0 ← (byte*) 0
|
||||
(byte) main::getScreen1_id#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::getScreen1
|
||||
main::getScreen1: scope:[main] from main
|
||||
(byte) main::getScreen1_id#1 ← phi( main/(byte) main::getScreen1_id#0 )
|
||||
(byte) main::getScreen1_$0#0 ← (byte) main::getScreen1_id#1 * (const byte) SIZEOF_POINTER
|
||||
(byte*) main::getScreen1_return#0 ← *((byte*[]) screens#0 + (byte) main::getScreen1_$0#0)
|
||||
to:main::getScreen1_@return
|
||||
main::getScreen1_@return: scope:[main] from main::getScreen1
|
||||
(byte*) main::getScreen1_return#2 ← phi( main::getScreen1/(byte*) main::getScreen1_return#0 )
|
||||
(byte*) main::getScreen1_return#1 ← (byte*) main::getScreen1_return#2
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::getScreen1_@return
|
||||
(byte*) main::getScreen1_return#3 ← phi( main::getScreen1_@return/(byte*) main::getScreen1_return#1 )
|
||||
(byte*~) main::$0 ← (byte*) main::getScreen1_return#3
|
||||
(byte*) main::screen#1 ← (byte*~) main::$0
|
||||
(byte*) main::spritePtr1_screen#0 ← (byte*) main::screen#1
|
||||
to:main::spritePtr1
|
||||
main::spritePtr1: scope:[main] from main::@1
|
||||
(byte*) main::spritePtr1_screen#1 ← phi( main::@1/(byte*) main::spritePtr1_screen#0 )
|
||||
(byte*) main::spritePtr1_$0#0 ← (byte*) main::spritePtr1_screen#1 + (word/signed word/dword/signed dword) $378
|
||||
(byte*) main::spritePtr1_$1#0 ← ((byte*)) (byte*) main::spritePtr1_$0#0
|
||||
(byte*) main::spritePtr1_return#0 ← (byte*) main::spritePtr1_$1#0
|
||||
to:main::spritePtr1_@return
|
||||
main::spritePtr1_@return: scope:[main] from main::spritePtr1
|
||||
(byte*) main::spritePtr1_return#2 ← phi( main::spritePtr1/(byte*) main::spritePtr1_return#0 )
|
||||
(byte*) main::spritePtr1_return#1 ← (byte*) main::spritePtr1_return#2
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::spritePtr1_@return
|
||||
(byte*) main::spritePtr1_return#3 ← phi( main::spritePtr1_@return/(byte*) main::spritePtr1_return#1 )
|
||||
(byte*~) main::$1 ← (byte*) main::spritePtr1_return#3
|
||||
*((byte*~) main::$1) ← (byte/signed byte/word/signed word/dword/signed dword) $22
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
return
|
||||
to:@return
|
||||
@3: scope:[] from @begin
|
||||
call main
|
||||
to:@4
|
||||
@4: scope:[] from @3
|
||||
to:@end
|
||||
@end: scope:[] from @4
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(byte*~) $0
|
||||
(byte*~) $1
|
||||
(label) @3
|
||||
(label) @4
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte*~) main::$0
|
||||
(byte*~) main::$1
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(label) main::getScreen1
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_$0#0
|
||||
(label) main::getScreen1_@return
|
||||
(byte) main::getScreen1_id
|
||||
(byte) main::getScreen1_id#0
|
||||
(byte) main::getScreen1_id#1
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0
|
||||
(byte*) main::getScreen1_return#1
|
||||
(byte*) main::getScreen1_return#2
|
||||
(byte*) main::getScreen1_return#3
|
||||
(byte*) main::screen
|
||||
(byte*) main::screen#0
|
||||
(byte*) main::screen#1
|
||||
(label) main::spritePtr1
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*) main::spritePtr1_$0#0
|
||||
(byte*~) main::spritePtr1_$1
|
||||
(byte*) main::spritePtr1_$1#0
|
||||
(label) main::spritePtr1_@return
|
||||
(byte*) main::spritePtr1_return
|
||||
(byte*) main::spritePtr1_return#0
|
||||
(byte*) main::spritePtr1_return#1
|
||||
(byte*) main::spritePtr1_return#2
|
||||
(byte*) main::spritePtr1_return#3
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*) main::spritePtr1_screen#0
|
||||
(byte*) main::spritePtr1_screen#1
|
||||
(byte*[]) screens
|
||||
(byte*[]) screens#0
|
||||
|
||||
Culled Empty Block (label) @4
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Alias (byte) main::getScreen1_id#0 = (byte) main::getScreen1_id#1
|
||||
Alias (byte*) main::getScreen1_return#0 = (byte*) main::getScreen1_return#2 (byte*) main::getScreen1_return#1 (byte*) main::getScreen1_return#3 (byte*~) main::$0 (byte*) main::screen#1 (byte*) main::spritePtr1_screen#0 (byte*) main::spritePtr1_screen#1
|
||||
Alias (byte*) main::spritePtr1_return#0 = (byte*) main::spritePtr1_$1#0 (byte*) main::spritePtr1_return#2 (byte*) main::spritePtr1_return#1 (byte*) main::spritePtr1_return#3 (byte*~) main::$1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Constant (const byte*) $0 = ((byte*))$400
|
||||
Constant (const byte*) $1 = ((byte*))$1400
|
||||
Constant (const byte*) main::screen#0 = 0
|
||||
Constant (const byte) main::getScreen1_id#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*[]) screens#0 = { $0, $1 }
|
||||
Constant (const byte) main::getScreen1_$0#0 = main::getScreen1_id#0*SIZEOF_POINTER
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(screens#0+main::getScreen1_$0#0)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Removing redundant cast (byte*) main::spritePtr1_return#0 ← ((byte*)) (byte*) main::spritePtr1_$0#0
|
||||
Successful SSA optimization Pass2EliminateRedundantCasts
|
||||
Culled Empty Block (label) main::getScreen1_@return
|
||||
Culled Empty Block (label) main::@1
|
||||
Culled Empty Block (label) main::spritePtr1_@return
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Alias (byte*) main::spritePtr1_return#0 = (byte*) main::spritePtr1_$0#0
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Constant inlined $0 = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
Constant inlined $1 = ((byte*))(word/signed word/dword/signed dword) $1400
|
||||
Constant inlined main::getScreen1_$0#0 = (const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @3
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Renumbering block @3 to @1
|
||||
Renumbering block main::@2 to main::@1
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::getScreen1
|
||||
main::getScreen1: scope:[main] from main
|
||||
[5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER)
|
||||
to:main::spritePtr1
|
||||
main::spritePtr1: scope:[main] from main::getScreen1
|
||||
[6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::spritePtr1
|
||||
[7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[8] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_id
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0 4.0
|
||||
(byte*) main::screen
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*~) main::spritePtr1_$1
|
||||
(byte*) main::spritePtr1_return
|
||||
(byte*) main::spritePtr1_return#0 4.0
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*[]) screens
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::getScreen1_return#0 to zero page equivalence class [ main::getScreen1_return#0 ]
|
||||
Added variable main::spritePtr1_return#0 to zero page equivalence class [ main::spritePtr1_return#0 ]
|
||||
Complete equivalence classes
|
||||
[ main::getScreen1_return#0 ]
|
||||
[ main::spritePtr1_return#0 ]
|
||||
Allocated zp ZP_WORD:2 [ main::getScreen1_return#0 ]
|
||||
Allocated zp ZP_WORD:4 [ main::spritePtr1_return#0 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_POINTER = 2
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1_return = 4
|
||||
jmp getScreen1
|
||||
//SEG11 main::getScreen1
|
||||
getScreen1:
|
||||
//SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
jmp spritePtr1
|
||||
//SEG13 main::spritePtr1
|
||||
spritePtr1:
|
||||
//SEG14 [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz2_plus_vwuc1
|
||||
lda getScreen1_return
|
||||
clc
|
||||
adc #<$378
|
||||
sta spritePtr1_return
|
||||
lda getScreen1_return+1
|
||||
adc #>$378
|
||||
sta spritePtr1_return+1
|
||||
jmp b1
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 -- _deref_pbuz1=vbuc1
|
||||
lda #$22
|
||||
ldy #0
|
||||
sta (spritePtr1_return),y
|
||||
jmp breturn
|
||||
//SEG17 main::@return
|
||||
breturn:
|
||||
//SEG18 [8] return
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) [ main::getScreen1_return#0 ] ( main:2 [ main::getScreen1_return#0 ] ) always clobbers reg byte a
|
||||
Statement [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 [ main::spritePtr1_return#0 ] ( main:2 [ main::spritePtr1_return#0 ] ) always clobbers reg byte a
|
||||
Statement [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
|
||||
Potential registers zp ZP_WORD:2 [ main::getScreen1_return#0 ] : zp ZP_WORD:2 ,
|
||||
Potential registers zp ZP_WORD:4 [ main::spritePtr1_return#0 ] : zp ZP_WORD:4 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 4: zp ZP_WORD:2 [ main::getScreen1_return#0 ] 4: zp ZP_WORD:4 [ main::spritePtr1_return#0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 99 combination zp ZP_WORD:2 [ main::getScreen1_return#0 ] zp ZP_WORD:4 [ main::spritePtr1_return#0 ]
|
||||
Uplifting [] best 99 combination
|
||||
Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ main::getScreen1_return#0 ] ] with [ zp ZP_WORD:4 [ main::spritePtr1_return#0 ] ] - score: 1
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_POINTER = 2
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1_return = 2
|
||||
jmp getScreen1
|
||||
//SEG11 main::getScreen1
|
||||
getScreen1:
|
||||
//SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
jmp spritePtr1
|
||||
//SEG13 main::spritePtr1
|
||||
spritePtr1:
|
||||
//SEG14 [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1
|
||||
clc
|
||||
lda spritePtr1_return
|
||||
adc #<$378
|
||||
sta spritePtr1_return
|
||||
lda spritePtr1_return+1
|
||||
adc #>$378
|
||||
sta spritePtr1_return+1
|
||||
jmp b1
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 -- _deref_pbuz1=vbuc1
|
||||
lda #$22
|
||||
ldy #0
|
||||
sta (spritePtr1_return),y
|
||||
jmp breturn
|
||||
//SEG17 main::@return
|
||||
breturn:
|
||||
//SEG18 [8] return
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp getScreen1
|
||||
Removing instruction jmp spritePtr1
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction getScreen1:
|
||||
Removing instruction spritePtr1:
|
||||
Removing instruction b1:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(label) main::getScreen1
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_id
|
||||
(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0
|
||||
(byte*) main::screen
|
||||
(label) main::spritePtr1
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*~) main::spritePtr1_$1
|
||||
(byte*) main::spritePtr1_return
|
||||
(byte*) main::spritePtr1_return#0 spritePtr1_return zp ZP_WORD:2 4.0
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*[]) screens
|
||||
(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 }
|
||||
|
||||
zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_return#0 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 48
|
||||
|
||||
//SEG0 File Comments
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_POINTER = 2
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG9 @end
|
||||
//SEG10 main
|
||||
main: {
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1_return = 2
|
||||
//SEG11 main::getScreen1
|
||||
//SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
//SEG13 main::spritePtr1
|
||||
//SEG14 [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1
|
||||
clc
|
||||
lda spritePtr1_return
|
||||
adc #<$378
|
||||
sta spritePtr1_return
|
||||
lda spritePtr1_return+1
|
||||
adc #>$378
|
||||
sta spritePtr1_return+1
|
||||
//SEG15 main::@1
|
||||
//SEG16 [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 -- _deref_pbuz1=vbuc1
|
||||
lda #$22
|
||||
ldy #0
|
||||
sta (spritePtr1_return),y
|
||||
//SEG17 main::@return
|
||||
//SEG18 [8] return
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
||||
|
24
src/test/ref/cast-not-needed-2.sym
Normal file
24
src/test/ref/cast-not-needed-2.sym
Normal file
@ -0,0 +1,24 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(label) main::getScreen1
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_id
|
||||
(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0
|
||||
(byte*) main::screen
|
||||
(label) main::spritePtr1
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*~) main::spritePtr1_$1
|
||||
(byte*) main::spritePtr1_return
|
||||
(byte*) main::spritePtr1_return#0 spritePtr1_return zp ZP_WORD:2 4.0
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*[]) screens
|
||||
(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 }
|
||||
|
||||
zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_return#0 ]
|
27
src/test/ref/cast-not-needed-3.asm
Normal file
27
src/test/ref/cast-not-needed-3.asm
Normal file
@ -0,0 +1,27 @@
|
||||
// Tests a cast that is not needed
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_POINTER = 2
|
||||
main: {
|
||||
.label DSP = $400
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1__0 = 2
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
clc
|
||||
lda spritePtr1__0
|
||||
adc #<$378
|
||||
sta spritePtr1__0
|
||||
lda spritePtr1__0+1
|
||||
adc #>$378
|
||||
sta spritePtr1__0+1
|
||||
ldy #0
|
||||
lda (spritePtr1__0),y
|
||||
sta DSP
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
25
src/test/ref/cast-not-needed-3.cfg
Normal file
25
src/test/ref/cast-not-needed-3.cfg
Normal file
@ -0,0 +1,25 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::getScreen1
|
||||
main::getScreen1: scope:[main] from main
|
||||
[5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER)
|
||||
to:main::spritePtr1
|
||||
main::spritePtr1: scope:[main] from main::getScreen1
|
||||
[6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378
|
||||
[7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0)
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::spritePtr1
|
||||
[8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[9] return
|
||||
to:@return
|
455
src/test/ref/cast-not-needed-3.log
Normal file
455
src/test/ref/cast-not-needed-3.log
Normal file
@ -0,0 +1,455 @@
|
||||
Fixing pointer array-indexing *((byte*[]) screens + (byte) getScreen::id)
|
||||
Identified constant variable (byte*) main::DSP
|
||||
Inlined call (byte*~) main::$0 ← call getScreen (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
Inlined call (byte~) main::$1 ← call spritePtr (byte*~) main::$0
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*~) $0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte*~) $1 ← ((byte*)) (word/signed word/dword/signed dword) $1400
|
||||
(byte*[]) screens#0 ← { (byte*~) $0, (byte*~) $1 }
|
||||
to:@3
|
||||
main: scope:[main] from @3
|
||||
(byte*) main::DSP#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte) main::getScreen1_id#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::getScreen1
|
||||
main::getScreen1: scope:[main] from main
|
||||
(byte) main::getScreen1_id#1 ← phi( main/(byte) main::getScreen1_id#0 )
|
||||
(byte) main::getScreen1_$0#0 ← (byte) main::getScreen1_id#1 * (const byte) SIZEOF_POINTER
|
||||
(byte*) main::getScreen1_return#0 ← *((byte*[]) screens#0 + (byte) main::getScreen1_$0#0)
|
||||
to:main::getScreen1_@return
|
||||
main::getScreen1_@return: scope:[main] from main::getScreen1
|
||||
(byte*) main::getScreen1_return#2 ← phi( main::getScreen1/(byte*) main::getScreen1_return#0 )
|
||||
(byte*) main::getScreen1_return#1 ← (byte*) main::getScreen1_return#2
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::getScreen1_@return
|
||||
(byte*) main::getScreen1_return#3 ← phi( main::getScreen1_@return/(byte*) main::getScreen1_return#1 )
|
||||
(byte*~) main::$0 ← (byte*) main::getScreen1_return#3
|
||||
(byte*) main::spritePtr1_screen#0 ← (byte*~) main::$0
|
||||
to:main::spritePtr1
|
||||
main::spritePtr1: scope:[main] from main::@1
|
||||
(byte*) main::spritePtr1_screen#1 ← phi( main::@1/(byte*) main::spritePtr1_screen#0 )
|
||||
(byte*) main::spritePtr1_$0#0 ← (byte*) main::spritePtr1_screen#1 + (word/signed word/dword/signed dword) $378
|
||||
(byte) main::spritePtr1_$1#0 ← ((byte)) *((byte*) main::spritePtr1_$0#0)
|
||||
(byte) main::spritePtr1_return#0 ← (byte) main::spritePtr1_$1#0
|
||||
to:main::spritePtr1_@return
|
||||
main::spritePtr1_@return: scope:[main] from main::spritePtr1
|
||||
(byte) main::spritePtr1_return#2 ← phi( main::spritePtr1/(byte) main::spritePtr1_return#0 )
|
||||
(byte) main::spritePtr1_return#1 ← (byte) main::spritePtr1_return#2
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::spritePtr1_@return
|
||||
(byte) main::spritePtr1_return#3 ← phi( main::spritePtr1_@return/(byte) main::spritePtr1_return#1 )
|
||||
(byte~) main::$1 ← (byte) main::spritePtr1_return#3
|
||||
*((byte*) main::DSP#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte~) main::$1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
return
|
||||
to:@return
|
||||
@3: scope:[] from @begin
|
||||
call main
|
||||
to:@4
|
||||
@4: scope:[] from @3
|
||||
to:@end
|
||||
@end: scope:[] from @4
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(byte*~) $0
|
||||
(byte*~) $1
|
||||
(label) @3
|
||||
(label) @4
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte*~) main::$0
|
||||
(byte~) main::$1
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte*) main::DSP
|
||||
(byte*) main::DSP#0
|
||||
(label) main::getScreen1
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_$0#0
|
||||
(label) main::getScreen1_@return
|
||||
(byte) main::getScreen1_id
|
||||
(byte) main::getScreen1_id#0
|
||||
(byte) main::getScreen1_id#1
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0
|
||||
(byte*) main::getScreen1_return#1
|
||||
(byte*) main::getScreen1_return#2
|
||||
(byte*) main::getScreen1_return#3
|
||||
(label) main::spritePtr1
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*) main::spritePtr1_$0#0
|
||||
(byte~) main::spritePtr1_$1
|
||||
(byte) main::spritePtr1_$1#0
|
||||
(label) main::spritePtr1_@return
|
||||
(byte) main::spritePtr1_return
|
||||
(byte) main::spritePtr1_return#0
|
||||
(byte) main::spritePtr1_return#1
|
||||
(byte) main::spritePtr1_return#2
|
||||
(byte) main::spritePtr1_return#3
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*) main::spritePtr1_screen#0
|
||||
(byte*) main::spritePtr1_screen#1
|
||||
(byte*[]) screens
|
||||
(byte*[]) screens#0
|
||||
|
||||
Culled Empty Block (label) @4
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Alias (byte) main::getScreen1_id#0 = (byte) main::getScreen1_id#1
|
||||
Alias (byte*) main::getScreen1_return#0 = (byte*) main::getScreen1_return#2 (byte*) main::getScreen1_return#1 (byte*) main::getScreen1_return#3 (byte*~) main::$0 (byte*) main::spritePtr1_screen#0 (byte*) main::spritePtr1_screen#1
|
||||
Alias (byte) main::spritePtr1_return#0 = (byte) main::spritePtr1_$1#0 (byte) main::spritePtr1_return#2 (byte) main::spritePtr1_return#1 (byte) main::spritePtr1_return#3 (byte~) main::$1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Constant (const byte*) $0 = ((byte*))$400
|
||||
Constant (const byte*) $1 = ((byte*))$1400
|
||||
Constant (const byte*) main::DSP#0 = ((byte*))$400
|
||||
Constant (const byte) main::getScreen1_id#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*[]) screens#0 = { $0, $1 }
|
||||
Constant (const byte) main::getScreen1_$0#0 = main::getScreen1_id#0*SIZEOF_POINTER
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(screens#0+main::getScreen1_$0#0)
|
||||
Consolidated array index constant in *(main::DSP#0+0)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing redundant cast (byte) main::spritePtr1_return#0 ← ((byte)) *((byte*) main::spritePtr1_$0#0)
|
||||
Successful SSA optimization Pass2EliminateRedundantCasts
|
||||
Culled Empty Block (label) main::getScreen1_@return
|
||||
Culled Empty Block (label) main::@1
|
||||
Culled Empty Block (label) main::spritePtr1_@return
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Constant inlined $0 = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
Constant inlined $1 = ((byte*))(word/signed word/dword/signed dword) $1400
|
||||
Constant inlined main::getScreen1_$0#0 = (const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Simplifying constant plus zero main::DSP#0+0
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @3
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Renumbering block @3 to @1
|
||||
Renumbering block main::@2 to main::@1
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::getScreen1
|
||||
main::getScreen1: scope:[main] from main
|
||||
[5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER)
|
||||
to:main::spritePtr1
|
||||
main::spritePtr1: scope:[main] from main::getScreen1
|
||||
[6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378
|
||||
[7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0)
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::spritePtr1
|
||||
[8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte*) main::DSP
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_id
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0 4.0
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*) main::spritePtr1_$0#0 4.0
|
||||
(byte~) main::spritePtr1_$1
|
||||
(byte) main::spritePtr1_return
|
||||
(byte) main::spritePtr1_return#0 4.0
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*[]) screens
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::getScreen1_return#0 to zero page equivalence class [ main::getScreen1_return#0 ]
|
||||
Added variable main::spritePtr1_$0#0 to zero page equivalence class [ main::spritePtr1_$0#0 ]
|
||||
Added variable main::spritePtr1_return#0 to zero page equivalence class [ main::spritePtr1_return#0 ]
|
||||
Complete equivalence classes
|
||||
[ main::getScreen1_return#0 ]
|
||||
[ main::spritePtr1_$0#0 ]
|
||||
[ main::spritePtr1_return#0 ]
|
||||
Allocated zp ZP_WORD:2 [ main::getScreen1_return#0 ]
|
||||
Allocated zp ZP_WORD:4 [ main::spritePtr1_$0#0 ]
|
||||
Allocated zp ZP_BYTE:6 [ main::spritePtr1_return#0 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_POINTER = 2
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label DSP = $400
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1__0 = 4
|
||||
.label spritePtr1_return = 6
|
||||
jmp getScreen1
|
||||
//SEG11 main::getScreen1
|
||||
getScreen1:
|
||||
//SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
jmp spritePtr1
|
||||
//SEG13 main::spritePtr1
|
||||
spritePtr1:
|
||||
//SEG14 [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz2_plus_vwuc1
|
||||
lda getScreen1_return
|
||||
clc
|
||||
adc #<$378
|
||||
sta spritePtr1__0
|
||||
lda getScreen1_return+1
|
||||
adc #>$378
|
||||
sta spritePtr1__0+1
|
||||
//SEG15 [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) -- vbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (spritePtr1__0),y
|
||||
sta spritePtr1_return
|
||||
jmp b1
|
||||
//SEG16 main::@1
|
||||
b1:
|
||||
//SEG17 [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 -- _deref_pbuc1=vbuz1
|
||||
lda spritePtr1_return
|
||||
sta DSP
|
||||
jmp breturn
|
||||
//SEG18 main::@return
|
||||
breturn:
|
||||
//SEG19 [9] return
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) [ main::getScreen1_return#0 ] ( main:2 [ main::getScreen1_return#0 ] ) always clobbers reg byte a
|
||||
Statement [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 [ main::spritePtr1_$0#0 ] ( main:2 [ main::spritePtr1_$0#0 ] ) always clobbers reg byte a
|
||||
Statement [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) [ main::spritePtr1_return#0 ] ( main:2 [ main::spritePtr1_return#0 ] ) always clobbers reg byte a reg byte y
|
||||
Potential registers zp ZP_WORD:2 [ main::getScreen1_return#0 ] : zp ZP_WORD:2 ,
|
||||
Potential registers zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] : zp ZP_WORD:4 ,
|
||||
Potential registers zp ZP_BYTE:6 [ main::spritePtr1_return#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 4: zp ZP_WORD:2 [ main::getScreen1_return#0 ] 4: zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] 4: zp ZP_BYTE:6 [ main::spritePtr1_return#0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 100 combination zp ZP_WORD:2 [ main::getScreen1_return#0 ] zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] reg byte a [ main::spritePtr1_return#0 ]
|
||||
Uplifting [] best 100 combination
|
||||
Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ main::getScreen1_return#0 ] ] with [ zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] ] - score: 1
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_POINTER = 2
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label DSP = $400
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1__0 = 2
|
||||
jmp getScreen1
|
||||
//SEG11 main::getScreen1
|
||||
getScreen1:
|
||||
//SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
jmp spritePtr1
|
||||
//SEG13 main::spritePtr1
|
||||
spritePtr1:
|
||||
//SEG14 [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1
|
||||
clc
|
||||
lda spritePtr1__0
|
||||
adc #<$378
|
||||
sta spritePtr1__0
|
||||
lda spritePtr1__0+1
|
||||
adc #>$378
|
||||
sta spritePtr1__0+1
|
||||
//SEG15 [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) -- vbuaa=_deref_pbuz1
|
||||
ldy #0
|
||||
lda (spritePtr1__0),y
|
||||
jmp b1
|
||||
//SEG16 main::@1
|
||||
b1:
|
||||
//SEG17 [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 -- _deref_pbuc1=vbuaa
|
||||
sta DSP
|
||||
jmp breturn
|
||||
//SEG18 main::@return
|
||||
breturn:
|
||||
//SEG19 [9] return
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp getScreen1
|
||||
Removing instruction jmp spritePtr1
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction getScreen1:
|
||||
Removing instruction spritePtr1:
|
||||
Removing instruction b1:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) main::DSP
|
||||
(const byte*) main::DSP#0 DSP = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
(label) main::getScreen1
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_id
|
||||
(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0
|
||||
(label) main::spritePtr1
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*) main::spritePtr1_$0#0 spritePtr1_$0 zp ZP_WORD:2 4.0
|
||||
(byte~) main::spritePtr1_$1
|
||||
(byte) main::spritePtr1_return
|
||||
(byte) main::spritePtr1_return#0 reg byte a 4.0
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*[]) screens
|
||||
(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 }
|
||||
|
||||
zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_$0#0 ]
|
||||
reg byte a [ main::spritePtr1_return#0 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 49
|
||||
|
||||
//SEG0 File Comments
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_POINTER = 2
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG9 @end
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label DSP = $400
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1__0 = 2
|
||||
//SEG11 main::getScreen1
|
||||
//SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
sta getScreen1_return+1
|
||||
//SEG13 main::spritePtr1
|
||||
//SEG14 [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1
|
||||
clc
|
||||
lda spritePtr1__0
|
||||
adc #<$378
|
||||
sta spritePtr1__0
|
||||
lda spritePtr1__0+1
|
||||
adc #>$378
|
||||
sta spritePtr1__0+1
|
||||
//SEG15 [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) -- vbuaa=_deref_pbuz1
|
||||
ldy #0
|
||||
lda (spritePtr1__0),y
|
||||
//SEG16 main::@1
|
||||
//SEG17 [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 -- _deref_pbuc1=vbuaa
|
||||
sta DSP
|
||||
//SEG18 main::@return
|
||||
//SEG19 [9] return
|
||||
rts
|
||||
}
|
||||
screens: .word $400, $1400
|
||||
|
27
src/test/ref/cast-not-needed-3.sym
Normal file
27
src/test/ref/cast-not-needed-3.sym
Normal file
@ -0,0 +1,27 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) main::DSP
|
||||
(const byte*) main::DSP#0 DSP = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
(label) main::getScreen1
|
||||
(byte) main::getScreen1_$0
|
||||
(byte) main::getScreen1_id
|
||||
(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
(byte*) main::getScreen1_return
|
||||
(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0
|
||||
(label) main::spritePtr1
|
||||
(byte*~) main::spritePtr1_$0
|
||||
(byte*) main::spritePtr1_$0#0 spritePtr1_$0 zp ZP_WORD:2 4.0
|
||||
(byte~) main::spritePtr1_$1
|
||||
(byte) main::spritePtr1_return
|
||||
(byte) main::spritePtr1_return#0 reg byte a 4.0
|
||||
(byte*) main::spritePtr1_screen
|
||||
(byte*[]) screens
|
||||
(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 }
|
||||
|
||||
zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_$0#0 ]
|
||||
reg byte a [ main::spritePtr1_return#0 ]
|
@ -1,4 +1,4 @@
|
||||
//
|
||||
// Tests a cast that is not needed
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
|
@ -99,7 +99,7 @@ Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
//
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
@ -146,7 +146,7 @@ Uplifting [] best 27 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
//
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
@ -218,7 +218,7 @@ FINAL ASSEMBLER
|
||||
Score: 12
|
||||
|
||||
//SEG0 File Comments
|
||||
//
|
||||
// Tests a cast that is not needed
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
|
212
src/test/ref/semi-struct-1.asm
Normal file
212
src/test/ref/semi-struct-1.asm
Normal file
@ -0,0 +1,212 @@
|
||||
// Implementing a semi-struct without the struct keyword by using pointer math and inline functions
|
||||
//
|
||||
// struct Point {
|
||||
// byte xpos; // The x-position
|
||||
// byte ypos; // The y-position
|
||||
// };
|
||||
// Point[NUM_POINTS] points;
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// The size of a point
|
||||
.const SIZEOF_POINT = 2
|
||||
// The number of points
|
||||
.const NUM_POINTS = 4
|
||||
.label print_char_cursor = 5
|
||||
.label print_line_cursor = 2
|
||||
// Initialize some points and print them
|
||||
main: {
|
||||
jsr init_points
|
||||
jsr print_points
|
||||
rts
|
||||
}
|
||||
// Print points
|
||||
print_points: {
|
||||
.label pointXpos1__0 = 9
|
||||
.label pointYpos1_return = 9
|
||||
jsr print_cls
|
||||
lda #<$400
|
||||
sta print_line_cursor
|
||||
lda #>$400
|
||||
sta print_line_cursor+1
|
||||
lda #<$400
|
||||
sta print_char_cursor
|
||||
lda #>$400
|
||||
sta print_char_cursor+1
|
||||
ldx #0
|
||||
b1:
|
||||
txa
|
||||
asl
|
||||
clc
|
||||
adc #<points
|
||||
sta pointXpos1__0
|
||||
lda #>points
|
||||
adc #0
|
||||
sta pointXpos1__0+1
|
||||
ldy #0
|
||||
lda (pointXpos1__0),y
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
jsr print_str
|
||||
inc pointYpos1_return
|
||||
bne !+
|
||||
inc pointYpos1_return+1
|
||||
!:
|
||||
ldy #0
|
||||
lda (pointYpos1_return),y
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
jsr print_ln
|
||||
inx
|
||||
cpx #NUM_POINTS-1+1
|
||||
bne b7
|
||||
rts
|
||||
b7:
|
||||
lda print_line_cursor
|
||||
sta print_char_cursor
|
||||
lda print_line_cursor+1
|
||||
sta print_char_cursor+1
|
||||
jmp b1
|
||||
str: .text " @"
|
||||
}
|
||||
// Print a newline
|
||||
print_ln: {
|
||||
b1:
|
||||
lda #$28
|
||||
clc
|
||||
adc print_line_cursor
|
||||
sta print_line_cursor
|
||||
bcc !+
|
||||
inc print_line_cursor+1
|
||||
!:
|
||||
lda print_line_cursor+1
|
||||
cmp print_char_cursor+1
|
||||
bcc b1
|
||||
bne !+
|
||||
lda print_line_cursor
|
||||
cmp print_char_cursor
|
||||
bcc b1
|
||||
!:
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX
|
||||
// print_byte(byte zeropage(4) b)
|
||||
print_byte: {
|
||||
.label b = 4
|
||||
lda b
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
tay
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
lda #$f
|
||||
and b
|
||||
tay
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
rts
|
||||
}
|
||||
// Print a single char
|
||||
// print_char(byte register(A) ch)
|
||||
print_char: {
|
||||
ldy #0
|
||||
sta (print_char_cursor),y
|
||||
inc print_char_cursor
|
||||
bne !+
|
||||
inc print_char_cursor+1
|
||||
!:
|
||||
rts
|
||||
}
|
||||
// Print a zero-terminated string
|
||||
// print_str(byte* zeropage(7) str)
|
||||
print_str: {
|
||||
.label str = 7
|
||||
lda #<print_points.str
|
||||
sta str
|
||||
lda #>print_points.str
|
||||
sta str+1
|
||||
b1:
|
||||
ldy #0
|
||||
lda (str),y
|
||||
cmp #'@'
|
||||
bne b2
|
||||
rts
|
||||
b2:
|
||||
ldy #0
|
||||
lda (str),y
|
||||
sta (print_char_cursor),y
|
||||
inc print_char_cursor
|
||||
bne !+
|
||||
inc print_char_cursor+1
|
||||
!:
|
||||
inc str
|
||||
bne !+
|
||||
inc str+1
|
||||
!:
|
||||
jmp b1
|
||||
}
|
||||
// Clear the screen. Also resets current line/char cursor.
|
||||
print_cls: {
|
||||
.label sc = 2
|
||||
lda #<$400
|
||||
sta sc
|
||||
lda #>$400
|
||||
sta sc+1
|
||||
b1:
|
||||
lda #' '
|
||||
ldy #0
|
||||
sta (sc),y
|
||||
inc sc
|
||||
bne !+
|
||||
inc sc+1
|
||||
!:
|
||||
lda sc+1
|
||||
cmp #>$400+$3e8
|
||||
bne b1
|
||||
lda sc
|
||||
cmp #<$400+$3e8
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// Initialize points
|
||||
init_points: {
|
||||
.label pointXpos1__0 = 2
|
||||
.label pointYpos1_return = 2
|
||||
.label i = 4
|
||||
ldx #$a
|
||||
lda #0
|
||||
sta i
|
||||
b1:
|
||||
lda i
|
||||
asl
|
||||
clc
|
||||
adc #<points
|
||||
sta pointXpos1__0
|
||||
lda #>points
|
||||
adc #0
|
||||
sta pointXpos1__0+1
|
||||
txa
|
||||
ldy #0
|
||||
sta (pointXpos1__0),y
|
||||
txa
|
||||
axs #-[$a]
|
||||
inc pointYpos1_return
|
||||
bne !+
|
||||
inc pointYpos1_return+1
|
||||
!:
|
||||
txa
|
||||
ldy #0
|
||||
sta (pointYpos1_return),y
|
||||
txa
|
||||
axs #-[$a]
|
||||
inc i
|
||||
lda #NUM_POINTS-1+1
|
||||
cmp i
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
print_hextab: .text "0123456789abcdef"
|
||||
// All points
|
||||
points: .fill NUM_POINTS*SIZEOF_POINT, 0
|
158
src/test/ref/semi-struct-1.cfg
Normal file
158
src/test/ref/semi-struct-1.cfg
Normal file
@ -0,0 +1,158 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
[5] call init_points
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
[6] phi()
|
||||
[7] call print_points
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[8] return
|
||||
to:@return
|
||||
print_points: scope:[print_points] from main::@1
|
||||
[9] phi()
|
||||
[10] call print_cls
|
||||
to:print_points::@1
|
||||
print_points::@1: scope:[print_points] from print_points print_points::@7
|
||||
[11] (byte*) print_line_cursor#24 ← phi( print_points::@7/(byte*) print_line_cursor#1 print_points/((byte*))(word/signed word/dword/signed dword) $400 )
|
||||
[11] (byte*) print_char_cursor#45 ← phi( print_points::@7/(byte*~) print_char_cursor#60 print_points/((byte*))(word/signed word/dword/signed dword) $400 )
|
||||
[11] (byte) print_points::i#10 ← phi( print_points::@7/(byte) print_points::i#1 print_points/(byte/signed byte/word/signed word/dword/signed dword) 0 )
|
||||
to:print_points::getPoint1
|
||||
print_points::getPoint1: scope:[print_points] from print_points::@1
|
||||
[12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0
|
||||
to:print_points::pointXpos1
|
||||
print_points::pointXpos1: scope:[print_points] from print_points::getPoint1
|
||||
[14] phi()
|
||||
to:print_points::@2
|
||||
print_points::@2: scope:[print_points] from print_points::pointXpos1
|
||||
[15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0)
|
||||
[16] call print_byte
|
||||
to:print_points::@4
|
||||
print_points::@4: scope:[print_points] from print_points::@2
|
||||
[17] phi()
|
||||
[18] call print_str
|
||||
to:print_points::pointYpos1
|
||||
print_points::pointYpos1: scope:[print_points] from print_points::@4
|
||||
[19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
to:print_points::@3
|
||||
print_points::@3: scope:[print_points] from print_points::pointYpos1
|
||||
[20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0)
|
||||
[21] call print_byte
|
||||
to:print_points::@5
|
||||
print_points::@5: scope:[print_points] from print_points::@3
|
||||
[22] phi()
|
||||
[23] call print_ln
|
||||
to:print_points::@6
|
||||
print_points::@6: scope:[print_points] from print_points::@5
|
||||
[24] (byte) print_points::i#1 ← ++ (byte) print_points::i#10
|
||||
[25] if((byte) print_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto print_points::@7
|
||||
to:print_points::@return
|
||||
print_points::@return: scope:[print_points] from print_points::@6
|
||||
[26] return
|
||||
to:@return
|
||||
print_points::@7: scope:[print_points] from print_points::@6
|
||||
[27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1
|
||||
to:print_points::@1
|
||||
print_ln: scope:[print_ln] from print_points::@5
|
||||
[28] phi()
|
||||
to:print_ln::@1
|
||||
print_ln::@1: scope:[print_ln] from print_ln print_ln::@1
|
||||
[29] (byte*) print_line_cursor#11 ← phi( print_ln/(byte*) print_line_cursor#24 print_ln::@1/(byte*) print_line_cursor#1 )
|
||||
[30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28
|
||||
[31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1
|
||||
to:print_ln::@return
|
||||
print_ln::@return: scope:[print_ln] from print_ln::@1
|
||||
[32] return
|
||||
to:@return
|
||||
print_byte: scope:[print_byte] from print_points::@2 print_points::@3
|
||||
[33] (byte*) print_char_cursor#42 ← phi( print_points::@2/(byte*) print_char_cursor#45 print_points::@3/(byte*) print_char_cursor#2 )
|
||||
[33] (byte) print_byte::b#2 ← phi( print_points::@2/(byte) print_byte::b#0 print_points::@3/(byte) print_byte::b#1 )
|
||||
[34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
[35] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0)
|
||||
[36] call print_char
|
||||
to:print_byte::@1
|
||||
print_byte::@1: scope:[print_byte] from print_byte
|
||||
[37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f
|
||||
[38] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2)
|
||||
[39] call print_char
|
||||
to:print_byte::@return
|
||||
print_byte::@return: scope:[print_byte] from print_byte::@1
|
||||
[40] return
|
||||
to:@return
|
||||
print_char: scope:[print_char] from print_byte print_byte::@1
|
||||
[41] (byte*) print_char_cursor#28 ← phi( print_byte/(byte*) print_char_cursor#42 print_byte::@1/(byte*) print_char_cursor#29 )
|
||||
[41] (byte) print_char::ch#2 ← phi( print_byte/(byte) print_char::ch#0 print_byte::@1/(byte) print_char::ch#1 )
|
||||
[42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2
|
||||
[43] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28
|
||||
to:print_char::@return
|
||||
print_char::@return: scope:[print_char] from print_char
|
||||
[44] return
|
||||
to:@return
|
||||
print_str: scope:[print_str] from print_points::@4
|
||||
[45] phi()
|
||||
to:print_str::@1
|
||||
print_str::@1: scope:[print_str] from print_str print_str::@2
|
||||
[46] (byte*) print_char_cursor#2 ← phi( print_str/(byte*) print_char_cursor#29 print_str::@2/(byte*) print_char_cursor#1 )
|
||||
[46] (byte*) print_str::str#2 ← phi( print_str/(const string) print_points::str print_str::@2/(byte*) print_str::str#0 )
|
||||
[47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2
|
||||
to:print_str::@return
|
||||
print_str::@return: scope:[print_str] from print_str::@1
|
||||
[48] return
|
||||
to:@return
|
||||
print_str::@2: scope:[print_str] from print_str::@1
|
||||
[49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2)
|
||||
[50] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2
|
||||
[51] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#2
|
||||
to:print_str::@1
|
||||
print_cls: scope:[print_cls] from print_points
|
||||
[52] phi()
|
||||
to:print_cls::@1
|
||||
print_cls::@1: scope:[print_cls] from print_cls print_cls::@1
|
||||
[53] (byte*) print_cls::sc#2 ← phi( print_cls/((byte*))(word/signed word/dword/signed dword) $400 print_cls::@1/(byte*) print_cls::sc#1 )
|
||||
[54] *((byte*) print_cls::sc#2) ← (byte) ' '
|
||||
[55] (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2
|
||||
[56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1
|
||||
to:print_cls::@return
|
||||
print_cls::@return: scope:[print_cls] from print_cls::@1
|
||||
[57] return
|
||||
to:@return
|
||||
init_points: scope:[init_points] from main
|
||||
[58] phi()
|
||||
to:init_points::@1
|
||||
init_points::@1: scope:[init_points] from init_points init_points::@3
|
||||
[59] (byte) init_points::pos#10 ← phi( init_points/(byte/signed byte/word/signed word/dword/signed dword) $a init_points::@3/(byte) init_points::pos#2 )
|
||||
[59] (byte) init_points::i#10 ← phi( init_points/(byte/signed byte/word/signed word/dword/signed dword) 0 init_points::@3/(byte) init_points::i#1 )
|
||||
to:init_points::getPoint1
|
||||
init_points::getPoint1: scope:[init_points] from init_points::@1
|
||||
[60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0
|
||||
to:init_points::pointXpos1
|
||||
init_points::pointXpos1: scope:[init_points] from init_points::getPoint1
|
||||
[62] phi()
|
||||
to:init_points::@2
|
||||
init_points::@2: scope:[init_points] from init_points::pointXpos1
|
||||
[63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10
|
||||
[64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a
|
||||
to:init_points::pointYpos1
|
||||
init_points::pointYpos1: scope:[init_points] from init_points::@2
|
||||
[65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
to:init_points::@3
|
||||
init_points::@3: scope:[init_points] from init_points::pointYpos1
|
||||
[66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1
|
||||
[67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a
|
||||
[68] (byte) init_points::i#1 ← ++ (byte) init_points::i#10
|
||||
[69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1
|
||||
to:init_points::@return
|
||||
init_points::@return: scope:[init_points] from init_points::@3
|
||||
[70] return
|
||||
to:@return
|
2896
src/test/ref/semi-struct-1.log
Normal file
2896
src/test/ref/semi-struct-1.log
Normal file
File diff suppressed because it is too large
Load Diff
135
src/test/ref/semi-struct-1.sym
Normal file
135
src/test/ref/semi-struct-1.sym
Normal file
@ -0,0 +1,135 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte) NUM_POINTS
|
||||
(const byte) NUM_POINTS#0 NUM_POINTS = (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
(byte) SIZEOF_POINT
|
||||
(const byte) SIZEOF_POINT#0 SIZEOF_POINT = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) init_points()
|
||||
(label) init_points::@1
|
||||
(label) init_points::@2
|
||||
(label) init_points::@3
|
||||
(label) init_points::@return
|
||||
(label) init_points::getPoint1
|
||||
(byte~) init_points::getPoint1_$0
|
||||
(byte) init_points::getPoint1_$0#0 reg byte a 22.0
|
||||
(byte*~) init_points::getPoint1_$1
|
||||
(byte) init_points::getPoint1_idx
|
||||
(byte*) init_points::getPoint1_return
|
||||
(byte) init_points::i
|
||||
(byte) init_points::i#1 i zp ZP_BYTE:4 16.5
|
||||
(byte) init_points::i#10 i zp ZP_BYTE:4 3.666666666666667
|
||||
(byte*) init_points::point
|
||||
(label) init_points::pointXpos1
|
||||
(byte*~) init_points::pointXpos1_$0
|
||||
(byte*) init_points::pointXpos1_$0#0 pointXpos1_$0 zp ZP_WORD:2 8.25
|
||||
(byte*~) init_points::pointXpos1_$1
|
||||
(byte*) init_points::pointXpos1_point
|
||||
(byte*) init_points::pointXpos1_return
|
||||
(label) init_points::pointYpos1
|
||||
(byte*~) init_points::pointYpos1_$0
|
||||
(byte*~) init_points::pointYpos1_$1
|
||||
(byte*) init_points::pointYpos1_point
|
||||
(byte*) init_points::pointYpos1_return
|
||||
(byte*) init_points::pointYpos1_return#0 pointYpos1_return zp ZP_WORD:2 22.0
|
||||
(byte) init_points::pos
|
||||
(byte) init_points::pos#1 reg byte x 11.0
|
||||
(byte) init_points::pos#10 reg byte x 6.6000000000000005
|
||||
(byte) init_points::pos#2 reg byte x 7.333333333333333
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte[NUM_POINTS#0*SIZEOF_POINT#0]) points
|
||||
(const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 points = { fill( NUM_POINTS#0*SIZEOF_POINT#0, 0) }
|
||||
(void()) print_byte((byte) print_byte::b)
|
||||
(byte~) print_byte::$0 reg byte a 4.0
|
||||
(byte~) print_byte::$2 reg byte a 4.0
|
||||
(label) print_byte::@1
|
||||
(label) print_byte::@return
|
||||
(byte) print_byte::b
|
||||
(byte) print_byte::b#0 b zp ZP_BYTE:4 22.0
|
||||
(byte) print_byte::b#1 b zp ZP_BYTE:4 22.0
|
||||
(byte) print_byte::b#2 b zp ZP_BYTE:4 6.5
|
||||
(void()) print_char((byte) print_char::ch)
|
||||
(label) print_char::@return
|
||||
(byte) print_char::ch
|
||||
(byte) print_char::ch#0 reg byte a 4.0
|
||||
(byte) print_char::ch#1 reg byte a 4.0
|
||||
(byte) print_char::ch#2 reg byte a 6.0
|
||||
(byte*) print_char_cursor
|
||||
(byte*) print_char_cursor#1 print_char_cursor zp ZP_WORD:5 101.0
|
||||
(byte*) print_char_cursor#2 print_char_cursor zp ZP_WORD:5 45.142857142857146
|
||||
(byte*) print_char_cursor#28 print_char_cursor zp ZP_WORD:5 4.0
|
||||
(byte*) print_char_cursor#29 print_char_cursor zp ZP_WORD:5 6.6875
|
||||
(byte*) print_char_cursor#42 print_char_cursor zp ZP_WORD:5 8.0
|
||||
(byte*) print_char_cursor#45 print_char_cursor zp ZP_WORD:5 4.4
|
||||
(byte*~) print_char_cursor#60 print_char_cursor zp ZP_WORD:5 22.0
|
||||
(void()) print_cls()
|
||||
(label) print_cls::@1
|
||||
(label) print_cls::@return
|
||||
(byte*) print_cls::sc
|
||||
(byte*) print_cls::sc#1 sc zp ZP_WORD:2 16.5
|
||||
(byte*) print_cls::sc#2 sc zp ZP_WORD:2 16.5
|
||||
(byte[]) print_hextab
|
||||
(const byte[]) print_hextab#0 print_hextab = (string) "0123456789abcdef"
|
||||
(byte*) print_line_cursor
|
||||
(byte*) print_line_cursor#1 print_line_cursor zp ZP_WORD:2 46.42857142857143
|
||||
(byte*) print_line_cursor#11 print_line_cursor zp ZP_WORD:2 204.0
|
||||
(byte*) print_line_cursor#24 print_line_cursor zp ZP_WORD:2 1.0
|
||||
(void()) print_ln()
|
||||
(label) print_ln::@1
|
||||
(label) print_ln::@return
|
||||
(void()) print_points()
|
||||
(label) print_points::@1
|
||||
(label) print_points::@2
|
||||
(label) print_points::@3
|
||||
(label) print_points::@4
|
||||
(label) print_points::@5
|
||||
(label) print_points::@6
|
||||
(label) print_points::@7
|
||||
(label) print_points::@return
|
||||
(label) print_points::getPoint1
|
||||
(byte~) print_points::getPoint1_$0
|
||||
(byte) print_points::getPoint1_$0#0 reg byte a 22.0
|
||||
(byte*~) print_points::getPoint1_$1
|
||||
(byte) print_points::getPoint1_idx
|
||||
(byte*) print_points::getPoint1_return
|
||||
(byte) print_points::i
|
||||
(byte) print_points::i#1 reg byte x 11.0
|
||||
(byte) print_points::i#10 reg byte x 2.5384615384615383
|
||||
(byte*) print_points::point
|
||||
(label) print_points::pointXpos1
|
||||
(byte*~) print_points::pointXpos1_$0
|
||||
(byte*) print_points::pointXpos1_$0#0 pointXpos1_$0 zp ZP_WORD:9 5.5
|
||||
(byte*~) print_points::pointXpos1_$1
|
||||
(byte*) print_points::pointXpos1_point
|
||||
(byte*) print_points::pointXpos1_return
|
||||
(label) print_points::pointYpos1
|
||||
(byte*~) print_points::pointYpos1_$0
|
||||
(byte*~) print_points::pointYpos1_$1
|
||||
(byte*) print_points::pointYpos1_point
|
||||
(byte*) print_points::pointYpos1_return
|
||||
(byte*) print_points::pointYpos1_return#0 pointYpos1_return zp ZP_WORD:9 22.0
|
||||
(const string) print_points::str str = (string) " @"
|
||||
(byte*) print_screen
|
||||
(void()) print_str((byte*) print_str::str)
|
||||
(label) print_str::@1
|
||||
(label) print_str::@2
|
||||
(label) print_str::@return
|
||||
(byte*) print_str::str
|
||||
(byte*) print_str::str#0 str zp ZP_WORD:7 202.0
|
||||
(byte*) print_str::str#2 str zp ZP_WORD:7 101.0
|
||||
|
||||
reg byte x [ print_points::i#10 print_points::i#1 ]
|
||||
zp ZP_WORD:2 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 print_cls::sc#2 print_cls::sc#1 init_points::pointXpos1_$0#0 init_points::pointYpos1_return#0 ]
|
||||
zp ZP_BYTE:4 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 init_points::i#10 init_points::i#1 ]
|
||||
reg byte a [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ]
|
||||
zp ZP_WORD:5 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ]
|
||||
zp ZP_WORD:7 [ print_str::str#2 print_str::str#0 ]
|
||||
reg byte x [ init_points::pos#10 init_points::pos#2 ]
|
||||
reg byte a [ print_points::getPoint1_$0#0 ]
|
||||
zp ZP_WORD:9 [ print_points::pointXpos1_$0#0 print_points::pointYpos1_return#0 ]
|
||||
reg byte a [ print_byte::$0 ]
|
||||
reg byte a [ print_byte::$2 ]
|
||||
reg byte a [ init_points::getPoint1_$0#0 ]
|
||||
reg byte x [ init_points::pos#1 ]
|
@ -30,7 +30,7 @@
|
||||
.label CIA1_PORT_B_DDR = $dc03
|
||||
.const KEY_SPACE = $3c
|
||||
// The size of a file ENTRY
|
||||
.const ENTRY_SIZE = $12
|
||||
.const SIZEOF_ENTRY = $12
|
||||
// The maximal number of files
|
||||
.const MAX_FILES = $90
|
||||
.label print_char_cursor = 6
|
||||
@ -912,7 +912,7 @@ mul8u: {
|
||||
.label mb = 2
|
||||
.label res = 9
|
||||
.label return = 9
|
||||
lda #ENTRY_SIZE
|
||||
lda #SIZEOF_ENTRY
|
||||
sta mb
|
||||
lda #0
|
||||
sta mb+1
|
||||
@ -958,4 +958,4 @@ keyboard_init: {
|
||||
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
|
||||
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
|
||||
// All files
|
||||
files: .fill MAX_FILES*ENTRY_SIZE, 0
|
||||
files: .fill MAX_FILES*SIZEOF_ENTRY, 0
|
||||
|
@ -18,7 +18,7 @@ main::fileEntry1: scope:[main] from main
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::fileEntry1
|
||||
[9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2
|
||||
[10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0
|
||||
[10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0
|
||||
to:main::fileEntry2
|
||||
main::fileEntry2: scope:[main] from main::@6
|
||||
[11] phi()
|
||||
@ -27,7 +27,7 @@ main::fileEntry2: scope:[main] from main::@6
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::fileEntry2
|
||||
[14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3
|
||||
[15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0
|
||||
[15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@7
|
||||
[16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0
|
||||
@ -530,7 +530,7 @@ mul8u: scope:[mul8u] from main::fileEntry1 main::fileEntry2
|
||||
[253] (byte) mul8u::a#6 ← phi( main::fileEntry1/(const byte) main::fileEntry1_idx#0 main::fileEntry2/(const byte) main::fileEntry2_idx#0 )
|
||||
to:mul8u::@1
|
||||
mul8u::@1: scope:[mul8u] from mul8u mul8u::@3
|
||||
[254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) ENTRY_SIZE#0 mul8u::@3/(word) mul8u::mb#1 )
|
||||
[254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) SIZEOF_ENTRY#0 mul8u::@3/(word) mul8u::mb#1 )
|
||||
[254] (word) mul8u::res#2 ← phi( mul8u/(byte/signed byte/word/signed word/dword/signed dword) 0 mul8u::@3/(word) mul8u::res#6 )
|
||||
[254] (byte) mul8u::a#3 ← phi( mul8u/(byte) mul8u::a#6 mul8u::@3/(byte) mul8u::a#0 )
|
||||
[255] if((byte) mul8u::a#3!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8u::@2
|
||||
|
@ -280,10 +280,10 @@ keyboard_key_pressed::@return: scope:[keyboard_key_pressed] from keyboard_key_p
|
||||
(byte*) print_screen#39 ← phi( @28/(byte*) print_screen#40 )
|
||||
(byte*) print_char_cursor#181 ← phi( @28/(byte*) print_char_cursor#182 )
|
||||
(byte*) print_line_cursor#99 ← phi( @28/(byte*) print_line_cursor#100 )
|
||||
(byte) ENTRY_SIZE#0 ← (byte/signed byte/word/signed word/dword/signed dword) $12
|
||||
(byte) SIZEOF_ENTRY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $12
|
||||
(byte) MAX_FILES#0 ← (byte/word/signed word/dword/signed dword) $90
|
||||
(word~) $1 ← ((word)) (byte) MAX_FILES#0
|
||||
(word~) $2 ← (word~) $1 * (byte) ENTRY_SIZE#0
|
||||
(word~) $2 ← (word~) $1 * (byte) SIZEOF_ENTRY#0
|
||||
(byte[$2]) files#0 ← { fill( $2, 0) }
|
||||
to:@52
|
||||
main: scope:[main] from @52
|
||||
@ -304,7 +304,7 @@ main::fileEntry1: scope:[main] from main::@15
|
||||
(byte*) print_screen#33 ← phi( main::@15/(byte*) print_screen#36 )
|
||||
(byte) main::fileEntry1_idx#1 ← phi( main::@15/(byte) main::fileEntry1_idx#0 )
|
||||
(byte) mul8u::a#1 ← (byte) main::fileEntry1_idx#1
|
||||
(byte) mul8u::b#0 ← (byte) ENTRY_SIZE#0
|
||||
(byte) mul8u::b#0 ← (byte) SIZEOF_ENTRY#0
|
||||
call mul8u
|
||||
(word) mul8u::return#2 ← (word) mul8u::return#1
|
||||
to:main::@16
|
||||
@ -340,7 +340,7 @@ main::fileEntry2: scope:[main] from main::@13
|
||||
(byte*) main::entry1#7 ← phi( main::@13/(byte*) main::entry1#0 )
|
||||
(byte) main::fileEntry2_idx#1 ← phi( main::@13/(byte) main::fileEntry2_idx#0 )
|
||||
(byte) mul8u::a#2 ← (byte) main::fileEntry2_idx#1
|
||||
(byte) mul8u::b#1 ← (byte) ENTRY_SIZE#0
|
||||
(byte) mul8u::b#1 ← (byte) SIZEOF_ENTRY#0
|
||||
call mul8u
|
||||
(word) mul8u::return#3 ← (word) mul8u::return#1
|
||||
to:main::@17
|
||||
@ -1548,12 +1548,12 @@ SYMBOL TABLE SSA
|
||||
(byte*) CIA1_PORT_B#0
|
||||
(byte*) CIA1_PORT_B_DDR
|
||||
(byte*) CIA1_PORT_B_DDR#0
|
||||
(byte) ENTRY_SIZE
|
||||
(byte) ENTRY_SIZE#0
|
||||
(byte) KEY_SPACE
|
||||
(byte) KEY_SPACE#0
|
||||
(byte) MAX_FILES
|
||||
(byte) MAX_FILES#0
|
||||
(byte) SIZEOF_ENTRY
|
||||
(byte) SIZEOF_ENTRY#0
|
||||
(byte[$2]) files
|
||||
(byte[$2]) files#0
|
||||
(void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n)
|
||||
@ -3162,7 +3162,7 @@ Constant (const byte*) CIA1_PORT_B_DDR#0 = ((byte*))$dc03
|
||||
Constant (const byte) KEY_SPACE#0 = $3c
|
||||
Constant (const byte[8]) keyboard_matrix_row_bitmask#0 = { $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f }
|
||||
Constant (const byte[8]) keyboard_matrix_col_bitmask#0 = { 1, 2, 4, 8, $10, $20, $40, $80 }
|
||||
Constant (const byte) ENTRY_SIZE#0 = $12
|
||||
Constant (const byte) SIZEOF_ENTRY#0 = $12
|
||||
Constant (const byte) MAX_FILES#0 = $90
|
||||
Constant (const byte) main::fileEntry1_idx#0 = 1
|
||||
Constant (const byte) main::fileEntry2_idx#0 = 2
|
||||
@ -3190,13 +3190,13 @@ Constant (const byte*) print_cls::sc#0 = print_line_cursor#0
|
||||
Constant (const byte*) print_cls::$0 = print_line_cursor#0+$3e8
|
||||
Constant (const word) $1 = ((word))MAX_FILES#0
|
||||
Constant (const byte) mul8u::a#1 = main::fileEntry1_idx#0
|
||||
Constant (const byte) mul8u::b#0 = ENTRY_SIZE#0
|
||||
Constant (const byte) mul8u::b#0 = SIZEOF_ENTRY#0
|
||||
Constant (const byte) mul8u::a#2 = main::fileEntry2_idx#0
|
||||
Constant (const byte) mul8u::b#1 = ENTRY_SIZE#0
|
||||
Constant (const byte) mul8u::b#1 = SIZEOF_ENTRY#0
|
||||
Constant (const byte) keyboard_key_pressed::key#0 = KEY_SPACE#0
|
||||
Constant (const byte) keyboard_key_pressed::key#1 = KEY_SPACE#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const word) $2 = $1*ENTRY_SIZE#0
|
||||
Constant (const word) $2 = $1*SIZEOF_ENTRY#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte[$2]) files#0 = { fill( $2, 0) }
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
@ -3308,7 +3308,7 @@ Constant inlined print_str::str#10 = (const string) printEntry::str5
|
||||
Constant inlined print_str::str#17 = (const string) printEntry::str12
|
||||
Constant inlined $1 = ((word))(const byte) MAX_FILES#0
|
||||
Constant inlined print_str::str#16 = (const string) printEntry::str11
|
||||
Constant inlined $2 = ((word))(const byte) MAX_FILES#0*(const byte) ENTRY_SIZE#0
|
||||
Constant inlined $2 = ((word))(const byte) MAX_FILES#0*(const byte) SIZEOF_ENTRY#0
|
||||
Constant inlined print_str::str#15 = (const string) printEntry::str10
|
||||
Constant inlined print_str::str#14 = (const string) printEntry::str9
|
||||
Constant inlined $3 = (const byte[]) print_hextab#0
|
||||
@ -3321,9 +3321,9 @@ Constant inlined print_cls::sc#0 = ((byte*))(word/signed word/dword/signed dword
|
||||
Constant inlined print_str::str#9 = (const string) printEntry::str4
|
||||
Constant inlined mul8u::res#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
Constant inlined mul8u::a#2 = (const byte) main::fileEntry2_idx#0
|
||||
Constant inlined mul8u::b#1 = (const byte) ENTRY_SIZE#0
|
||||
Constant inlined mul8u::b#1 = (const byte) SIZEOF_ENTRY#0
|
||||
Constant inlined mul8u::a#1 = (const byte) main::fileEntry1_idx#0
|
||||
Constant inlined mul8u::b#0 = (const byte) ENTRY_SIZE#0
|
||||
Constant inlined mul8u::b#0 = (const byte) SIZEOF_ENTRY#0
|
||||
Constant inlined print_str::str#4 = (const string) main::str1
|
||||
Constant inlined print_str::str#3 = (const string) main::str2
|
||||
Constant inlined print_str::str#2 = (const string) main::str1
|
||||
@ -3333,10 +3333,10 @@ Constant inlined print_str::str#7 = (const string) printEntry::str2
|
||||
Constant inlined print_str::str#6 = (const string) printEntry::str1
|
||||
Constant inlined print_str::str#5 = (const string) printEntry::str
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Identical Phi Values (byte) mul8u::b#2 (const byte) ENTRY_SIZE#0
|
||||
Identical Phi Values (byte) mul8u::b#2 (const byte) SIZEOF_ENTRY#0
|
||||
Identical Phi Values (byte) keyboard_key_pressed::key#2 (const byte) KEY_SPACE#0
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Constant (const word) mul8u::mb#0 = ((word))ENTRY_SIZE#0
|
||||
Constant (const word) mul8u::mb#0 = ((word))SIZEOF_ENTRY#0
|
||||
Constant (const byte) keyboard_key_pressed::colidx#0 = KEY_SPACE#0&7
|
||||
Constant (const byte) keyboard_key_pressed::rowidx#0 = KEY_SPACE#0>>3
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
@ -3346,7 +3346,7 @@ Consolidated array index constant in *(keyboard_matrix_row_bitmask#0+keyboard_ma
|
||||
Consolidated array index constant in *(keyboard_matrix_col_bitmask#0+keyboard_key_pressed::colidx#0)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Inlining constant with var siblings (const word) mul8u::mb#0
|
||||
Constant inlined mul8u::mb#0 = ((word))(const byte) ENTRY_SIZE#0
|
||||
Constant inlined mul8u::mb#0 = ((word))(const byte) SIZEOF_ENTRY#0
|
||||
Constant inlined keyboard_matrix_read::rowid#0 = (const byte) keyboard_key_pressed::rowidx#0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Added new block during phi lifting print_cls::@3(between print_cls::@1 and print_cls::@1)
|
||||
@ -3564,7 +3564,7 @@ main::fileEntry1: scope:[main] from main
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::fileEntry1
|
||||
[9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2
|
||||
[10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0
|
||||
[10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0
|
||||
to:main::fileEntry2
|
||||
main::fileEntry2: scope:[main] from main::@6
|
||||
[11] phi()
|
||||
@ -3573,7 +3573,7 @@ main::fileEntry2: scope:[main] from main::@6
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::fileEntry2
|
||||
[14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3
|
||||
[15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0
|
||||
[15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@7
|
||||
[16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0
|
||||
@ -4076,7 +4076,7 @@ mul8u: scope:[mul8u] from main::fileEntry1 main::fileEntry2
|
||||
[253] (byte) mul8u::a#6 ← phi( main::fileEntry1/(const byte) main::fileEntry1_idx#0 main::fileEntry2/(const byte) main::fileEntry2_idx#0 )
|
||||
to:mul8u::@1
|
||||
mul8u::@1: scope:[mul8u] from mul8u mul8u::@3
|
||||
[254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) ENTRY_SIZE#0 mul8u::@3/(word) mul8u::mb#1 )
|
||||
[254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) SIZEOF_ENTRY#0 mul8u::@3/(word) mul8u::mb#1 )
|
||||
[254] (word) mul8u::res#2 ← phi( mul8u/(byte/signed byte/word/signed word/dword/signed dword) 0 mul8u::@3/(word) mul8u::res#6 )
|
||||
[254] (byte) mul8u::a#3 ← phi( mul8u/(byte) mul8u::a#6 mul8u::@3/(byte) mul8u::a#0 )
|
||||
[255] if((byte) mul8u::a#3!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8u::@2
|
||||
@ -4110,10 +4110,10 @@ VARIABLE REGISTER WEIGHTS
|
||||
(byte*) CIA1_PORT_A_DDR
|
||||
(byte*) CIA1_PORT_B
|
||||
(byte*) CIA1_PORT_B_DDR
|
||||
(byte) ENTRY_SIZE
|
||||
(byte) KEY_SPACE
|
||||
(byte) MAX_FILES
|
||||
(byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files
|
||||
(byte) SIZEOF_ENTRY
|
||||
(byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files
|
||||
(void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n)
|
||||
(byte/signed word/word/dword/signed dword~) initEntry::$1 4.0
|
||||
(byte/signed word/word/dword/signed dword~) initEntry::$11 4.0
|
||||
@ -4676,7 +4676,7 @@ INITIAL ASM
|
||||
.label CIA1_PORT_B_DDR = $dc03
|
||||
.const KEY_SPACE = $3c
|
||||
// The size of a file ENTRY
|
||||
.const ENTRY_SIZE = $12
|
||||
.const SIZEOF_ENTRY = $12
|
||||
// The maximal number of files
|
||||
.const MAX_FILES = $90
|
||||
.label print_char_cursor = $c
|
||||
@ -4755,7 +4755,7 @@ main: {
|
||||
sta fileEntry1__0
|
||||
lda mul8u.return+1
|
||||
sta fileEntry1__0+1
|
||||
//SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz2
|
||||
//SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz2
|
||||
lda fileEntry1__0
|
||||
clc
|
||||
adc #<files
|
||||
@ -4788,7 +4788,7 @@ main: {
|
||||
sta fileEntry2__0
|
||||
lda mul8u.return_3+1
|
||||
sta fileEntry2__0+1
|
||||
//SEG29 [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 -- pbuz1=pbuc1_plus_vwuz2
|
||||
//SEG29 [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 -- pbuz1=pbuc1_plus_vwuz2
|
||||
lda fileEntry2__0
|
||||
clc
|
||||
adc #<files
|
||||
@ -6562,8 +6562,8 @@ mul8u: {
|
||||
.label return_3 = $1e
|
||||
//SEG561 [254] phi from mul8u to mul8u::@1 [phi:mul8u->mul8u::@1]
|
||||
b1_from_mul8u:
|
||||
//SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) ENTRY_SIZE#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1
|
||||
lda #ENTRY_SIZE
|
||||
//SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) SIZEOF_ENTRY#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1
|
||||
lda #SIZEOF_ENTRY
|
||||
sta mb
|
||||
lda #0
|
||||
sta mb+1
|
||||
@ -6648,15 +6648,15 @@ keyboard_init: {
|
||||
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
|
||||
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
|
||||
// All files
|
||||
files: .fill MAX_FILES*ENTRY_SIZE, 0
|
||||
files: .fill MAX_FILES*SIZEOF_ENTRY, 0
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [8] (word) mul8u::return#2 ← (word) mul8u::res#2 [ mul8u::return#2 ] ( main:2 [ mul8u::return#2 ] ) always clobbers reg byte a
|
||||
Statement [9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2 [ main::fileEntry1_$0#0 ] ( main:2 [ main::fileEntry1_$0#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a
|
||||
Statement [13] (word) mul8u::return#3 ← (word) mul8u::res#2 [ main::entry1#0 mul8u::return#3 ] ( main:2 [ main::entry1#0 mul8u::return#3 ] ) always clobbers reg byte a
|
||||
Statement [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3 [ main::entry1#0 main::fileEntry2_$0#0 ] ( main:2 [ main::entry1#0 main::fileEntry2_$0#0 ] ) always clobbers reg byte a
|
||||
Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a
|
||||
Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a
|
||||
Statement [16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ) always clobbers reg byte a
|
||||
Statement [18] (byte*) initEntry::entry#1 ← (byte*) main::entry2#0 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ) always clobbers reg byte a
|
||||
Statement [26] (byte*~) print_line_cursor#159 ← (byte*) print_line_cursor#1 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ( main:2 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ) always clobbers reg byte a
|
||||
@ -6792,10 +6792,10 @@ Statement [263] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dw
|
||||
Statement [264] *((const byte*) CIA1_PORT_B_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2::keyboard_init:5 [ ] ) always clobbers reg byte a
|
||||
Statement [8] (word) mul8u::return#2 ← (word) mul8u::res#2 [ mul8u::return#2 ] ( main:2 [ mul8u::return#2 ] ) always clobbers reg byte a
|
||||
Statement [9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2 [ main::fileEntry1_$0#0 ] ( main:2 [ main::fileEntry1_$0#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a
|
||||
Statement [13] (word) mul8u::return#3 ← (word) mul8u::res#2 [ main::entry1#0 mul8u::return#3 ] ( main:2 [ main::entry1#0 mul8u::return#3 ] ) always clobbers reg byte a
|
||||
Statement [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3 [ main::entry1#0 main::fileEntry2_$0#0 ] ( main:2 [ main::entry1#0 main::fileEntry2_$0#0 ] ) always clobbers reg byte a
|
||||
Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a
|
||||
Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a
|
||||
Statement [16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ) always clobbers reg byte a
|
||||
Statement [18] (byte*) initEntry::entry#1 ← (byte*) main::entry2#0 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ) always clobbers reg byte a
|
||||
Statement [26] (byte*~) print_line_cursor#159 ← (byte*) print_line_cursor#1 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ( main:2 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ) always clobbers reg byte a
|
||||
@ -7143,7 +7143,7 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
.label CIA1_PORT_B_DDR = $dc03
|
||||
.const KEY_SPACE = $3c
|
||||
// The size of a file ENTRY
|
||||
.const ENTRY_SIZE = $12
|
||||
.const SIZEOF_ENTRY = $12
|
||||
// The maximal number of files
|
||||
.const MAX_FILES = $90
|
||||
.label print_char_cursor = 6
|
||||
@ -7215,7 +7215,7 @@ main: {
|
||||
sta fileEntry1__0
|
||||
lda mul8u.return+1
|
||||
sta fileEntry1__0+1
|
||||
//SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
//SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
clc
|
||||
lda entry1
|
||||
adc #<files
|
||||
@ -7239,7 +7239,7 @@ main: {
|
||||
//SEG27 main::@7
|
||||
b7:
|
||||
//SEG28 [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3
|
||||
//SEG29 [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
//SEG29 [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
clc
|
||||
lda entry2
|
||||
adc #<files
|
||||
@ -8919,8 +8919,8 @@ mul8u: {
|
||||
.label return = 9
|
||||
//SEG561 [254] phi from mul8u to mul8u::@1 [phi:mul8u->mul8u::@1]
|
||||
b1_from_mul8u:
|
||||
//SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) ENTRY_SIZE#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1
|
||||
lda #ENTRY_SIZE
|
||||
//SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) SIZEOF_ENTRY#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1
|
||||
lda #SIZEOF_ENTRY
|
||||
sta mb
|
||||
lda #0
|
||||
sta mb+1
|
||||
@ -9004,7 +9004,7 @@ keyboard_init: {
|
||||
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
|
||||
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
|
||||
// All files
|
||||
files: .fill MAX_FILES*ENTRY_SIZE, 0
|
||||
files: .fill MAX_FILES*SIZEOF_ENTRY, 0
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
@ -9390,14 +9390,14 @@ FINAL SYMBOL TABLE
|
||||
(const byte*) CIA1_PORT_B#0 CIA1_PORT_B = ((byte*))(word/dword/signed dword) $dc01
|
||||
(byte*) CIA1_PORT_B_DDR
|
||||
(const byte*) CIA1_PORT_B_DDR#0 CIA1_PORT_B_DDR = ((byte*))(word/dword/signed dword) $dc03
|
||||
(byte) ENTRY_SIZE
|
||||
(const byte) ENTRY_SIZE#0 ENTRY_SIZE = (byte/signed byte/word/signed word/dword/signed dword) $12
|
||||
(byte) KEY_SPACE
|
||||
(const byte) KEY_SPACE#0 KEY_SPACE = (byte/signed byte/word/signed word/dword/signed dword) $3c
|
||||
(byte) MAX_FILES
|
||||
(const byte) MAX_FILES#0 MAX_FILES = (byte/word/signed word/dword/signed dword) $90
|
||||
(byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files
|
||||
(const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 files = { fill( ((word))MAX_FILES#0*ENTRY_SIZE#0, 0) }
|
||||
(byte) SIZEOF_ENTRY
|
||||
(const byte) SIZEOF_ENTRY#0 SIZEOF_ENTRY = (byte/signed byte/word/signed word/dword/signed dword) $12
|
||||
(byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files
|
||||
(const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 files = { fill( ((word))MAX_FILES#0*SIZEOF_ENTRY#0, 0) }
|
||||
(void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n)
|
||||
(byte/signed word/word/dword/signed dword~) initEntry::$1 reg byte a 4.0
|
||||
(byte/signed word/word/dword/signed dword~) initEntry::$11 reg byte a 4.0
|
||||
@ -9910,7 +9910,7 @@ Score: 4447
|
||||
.label CIA1_PORT_B_DDR = $dc03
|
||||
.const KEY_SPACE = $3c
|
||||
// The size of a file ENTRY
|
||||
.const ENTRY_SIZE = $12
|
||||
.const SIZEOF_ENTRY = $12
|
||||
// The maximal number of files
|
||||
.const MAX_FILES = $90
|
||||
.label print_char_cursor = 6
|
||||
@ -9967,7 +9967,7 @@ main: {
|
||||
sta fileEntry1__0
|
||||
lda mul8u.return+1
|
||||
sta fileEntry1__0+1
|
||||
//SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
//SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
clc
|
||||
lda entry1
|
||||
adc #<files
|
||||
@ -9985,7 +9985,7 @@ main: {
|
||||
//SEG26 [13] (word) mul8u::return#3 ← (word) mul8u::res#2
|
||||
//SEG27 main::@7
|
||||
//SEG28 [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3
|
||||
//SEG29 [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
//SEG29 [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 -- pbuz1=pbuc1_plus_vwuz1
|
||||
clc
|
||||
lda entry2
|
||||
adc #<files
|
||||
@ -11351,8 +11351,8 @@ mul8u: {
|
||||
.label res = 9
|
||||
.label return = 9
|
||||
//SEG561 [254] phi from mul8u to mul8u::@1 [phi:mul8u->mul8u::@1]
|
||||
//SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) ENTRY_SIZE#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1
|
||||
lda #ENTRY_SIZE
|
||||
//SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) SIZEOF_ENTRY#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1
|
||||
lda #SIZEOF_ENTRY
|
||||
sta mb
|
||||
lda #0
|
||||
sta mb+1
|
||||
@ -11423,5 +11423,5 @@ keyboard_init: {
|
||||
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
|
||||
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
|
||||
// All files
|
||||
files: .fill MAX_FILES*ENTRY_SIZE, 0
|
||||
files: .fill MAX_FILES*SIZEOF_ENTRY, 0
|
||||
|
||||
|
@ -9,14 +9,14 @@
|
||||
(const byte*) CIA1_PORT_B#0 CIA1_PORT_B = ((byte*))(word/dword/signed dword) $dc01
|
||||
(byte*) CIA1_PORT_B_DDR
|
||||
(const byte*) CIA1_PORT_B_DDR#0 CIA1_PORT_B_DDR = ((byte*))(word/dword/signed dword) $dc03
|
||||
(byte) ENTRY_SIZE
|
||||
(const byte) ENTRY_SIZE#0 ENTRY_SIZE = (byte/signed byte/word/signed word/dword/signed dword) $12
|
||||
(byte) KEY_SPACE
|
||||
(const byte) KEY_SPACE#0 KEY_SPACE = (byte/signed byte/word/signed word/dword/signed dword) $3c
|
||||
(byte) MAX_FILES
|
||||
(const byte) MAX_FILES#0 MAX_FILES = (byte/word/signed word/dword/signed dword) $90
|
||||
(byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files
|
||||
(const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 files = { fill( ((word))MAX_FILES#0*ENTRY_SIZE#0, 0) }
|
||||
(byte) SIZEOF_ENTRY
|
||||
(const byte) SIZEOF_ENTRY#0 SIZEOF_ENTRY = (byte/signed byte/word/signed word/dword/signed dword) $12
|
||||
(byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files
|
||||
(const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 files = { fill( ((word))MAX_FILES#0*SIZEOF_ENTRY#0, 0) }
|
||||
(void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n)
|
||||
(byte/signed word/word/dword/signed dword~) initEntry::$1 reg byte a 4.0
|
||||
(byte/signed word/word/dword/signed dword~) initEntry::$11 reg byte a 4.0
|
||||
|
Loading…
Reference in New Issue
Block a user