mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 04:49:27 +00:00
Fixed problems with sizeof()-handling struct members. Closes #230
This commit is contained in:
parent
a9e0c7805f
commit
0c33353bf8
@ -9,12 +9,14 @@ import dk.camelot64.kickc.model.operators.OperatorSizeOf;
|
||||
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.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
|
||||
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.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@ -38,25 +40,22 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if((assignment.getrValue1() == null) && (assignment.getOperator() != null) && (assignment.getrValue2() instanceof VariableRef)) {
|
||||
if((assignment.getrValue1() == null) && (assignment.getOperator() != null) && (assignment.getrValue2() != null)) {
|
||||
fixPointerUnary(assignment);
|
||||
} else if((assignment.getrValue1() instanceof VariableRef) && (assignment.getOperator() != null) && (assignment.getrValue2() != null)) {
|
||||
} else if((assignment.getrValue1() != null) && (assignment.getOperator() != null) && (assignment.getrValue2() != null)) {
|
||||
fixPointerBinary(block, stmtIt, assignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each statement maps RValues used as index to the new *2 variable created
|
||||
// For each statement maps RValues used as index to the new *sizeof() variable created
|
||||
Map<Statement, Map<RValue, VariableRef>> handled = new LinkedHashMap<>();
|
||||
|
||||
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof PointerDereferenceIndexed) {
|
||||
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) programValue.get();
|
||||
if(deref.getPointer() instanceof VariableRef) {
|
||||
VariableRef varRef = (VariableRef) deref.getPointer();
|
||||
Variable variable = getScope().getVariable(varRef);
|
||||
SymbolTypePointer pointerType = (SymbolTypePointer) variable.getType();
|
||||
SymbolTypePointer pointerType = getPointerType(deref.getPointer());
|
||||
if(pointerType != null) {
|
||||
if(pointerType.getElementType().getSizeBytes() > 1) {
|
||||
// Array-indexing into a non-byte pointer - multiply by sizeof()
|
||||
getLog().append("Fixing pointer array-indexing " + deref.toString(getProgram()));
|
||||
@ -78,7 +77,6 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -89,10 +87,8 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
*/
|
||||
|
||||
public void fixPointerBinary(ControlFlowBlock block, ListIterator<Statement> stmtIt, StatementAssignment assignment) {
|
||||
VariableRef varRef = (VariableRef) assignment.getrValue1();
|
||||
Variable variable = getScope().getVariable(varRef);
|
||||
if(variable.getType() instanceof SymbolTypePointer) {
|
||||
SymbolTypePointer pointerType = (SymbolTypePointer) variable.getType();
|
||||
SymbolTypePointer pointerType = getPointerType(assignment.getrValue1());
|
||||
if(pointerType != null) {
|
||||
if(SymbolType.VOID.equals(pointerType.getElementType())) {
|
||||
if(Operators.PLUS.equals(assignment.getOperator()) || Operators.MINUS.equals(assignment.getOperator())) {
|
||||
throw new CompileError("Void pointer math not allowed. ", assignment);
|
||||
@ -139,11 +135,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
* @param assignment The assignment statement
|
||||
*/
|
||||
public void fixPointerUnary(StatementAssignment assignment) {
|
||||
// Found assignment of unary operator
|
||||
VariableRef varRef = (VariableRef) assignment.getrValue2();
|
||||
Variable variable = getScope().getVariable(varRef);
|
||||
if(variable.getType() instanceof SymbolTypePointer) {
|
||||
SymbolTypePointer pointerType = (SymbolTypePointer) variable.getType();
|
||||
// Found assignment with unary operator
|
||||
SymbolTypePointer pointerType = getPointerType(assignment.getrValue2());
|
||||
if(pointerType != null) {
|
||||
if(SymbolType.VOID.equals(pointerType.getElementType())) {
|
||||
if(Operators.INCREMENT.equals(assignment.getOperator()) || Operators.DECREMENT.equals(assignment.getOperator())) {
|
||||
throw new CompileError("Void pointer math not allowed. ", assignment);
|
||||
@ -168,5 +162,34 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the passed value to determine if it is a pointer.
|
||||
* If it is a pointer return the type of the pointer
|
||||
* @param pointer The potential pointer to examine
|
||||
* @return The type of the pointer - if the value was a pointer. null if the value is not a pointer.
|
||||
*/
|
||||
private SymbolTypePointer getPointerType(RValue pointer) {
|
||||
if(pointer instanceof VariableRef) {
|
||||
VariableRef varRef = (VariableRef) pointer;
|
||||
Variable variable = getScope().getVariable(varRef);
|
||||
SymbolType type = variable.getType();
|
||||
if(type instanceof SymbolTypePointer) {
|
||||
return (SymbolTypePointer) type;
|
||||
}
|
||||
} else if(pointer instanceof StructMemberRef) {
|
||||
StructMemberRef structMemberRef = (StructMemberRef) pointer;
|
||||
RValue struct = structMemberRef.getStruct();
|
||||
SymbolType structType = SymbolTypeInference.inferType(getScope(), struct);
|
||||
if(structType instanceof SymbolTypeStruct) {
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) structType).getStructDefinition(getScope());
|
||||
Variable memberVariable = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
SymbolType memberType = memberVariable.getType();
|
||||
if(memberType instanceof SymbolTypePointer) {
|
||||
return (SymbolTypePointer) memberType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,11 +8,7 @@ struct RadixInfo {
|
||||
|
||||
void main() {
|
||||
const unsigned int* SCREEN = 0x400;
|
||||
for( byte radix: 0..1) {
|
||||
struct RadixInfo info = { RADIX_DECIMAL_VALUES };
|
||||
for( char digit: 0..4 ) {
|
||||
unsigned int digit_value = info.values[digit];
|
||||
SCREEN[digit] = digit_value;
|
||||
}
|
||||
}
|
||||
SCREEN[0] = info.values[1];
|
||||
SCREEN[1] = RADIX_DECIMAL_VALUES[1];
|
||||
}
|
@ -2,33 +2,17 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_WORD = 2
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label digit_value = 3
|
||||
.label radix = 2
|
||||
lda #0
|
||||
sta radix
|
||||
b1:
|
||||
ldx #0
|
||||
b2:
|
||||
lda RADIX_DECIMAL_VALUES,x
|
||||
sta digit_value
|
||||
lda RADIX_DECIMAL_VALUES+1,x
|
||||
sta digit_value+1
|
||||
txa
|
||||
asl
|
||||
tay
|
||||
lda digit_value
|
||||
sta SCREEN,y
|
||||
lda digit_value+1
|
||||
sta SCREEN+1,y
|
||||
inx
|
||||
cpx #5
|
||||
bne b2
|
||||
inc radix
|
||||
lda #2
|
||||
cmp radix
|
||||
bne b1
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN+1*SIZEOF_WORD
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1*SIZEOF_WORD+1
|
||||
rts
|
||||
}
|
||||
RADIX_DECIMAL_VALUES: .word $2710, $3e8, $64, $a
|
||||
|
@ -8,23 +8,9 @@
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (byte) main::radix#4 ← phi( main/(byte) 0 main::@3/(byte) main::radix#1 )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1 main::@2
|
||||
[6] (byte) main::digit#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::digit#1 )
|
||||
[7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2)
|
||||
[8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1
|
||||
[9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0
|
||||
[10] (byte) main::digit#1 ← ++ (byte) main::digit#2
|
||||
[11] if((byte) main::digit#1!=(byte) 5) goto main::@2
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
[12] (byte) main::radix#1 ← ++ (byte) main::radix#4
|
||||
[13] if((byte) main::radix#1!=(byte) 2) goto main::@1
|
||||
[4] *((const word*) main::SCREEN#0) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD)
|
||||
[5] *((const word*) main::SCREEN#0+(byte) 1*(const byte) SIZEOF_WORD) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD)
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[14] return
|
||||
main::@return: scope:[main] from main
|
||||
[6] return
|
||||
to:@return
|
||||
|
@ -1,9 +1,11 @@
|
||||
Fixing pointer array-indexing *((word*) main::SCREEN + (byte) main::digit)
|
||||
Fixing pointer array-indexing *((struct RadixInfo) main::info.values + (number) 1)
|
||||
Fixing pointer array-indexing *((word*) main::SCREEN + (number) 0)
|
||||
Fixing pointer array-indexing *((word[]) RADIX_DECIMAL_VALUES + (number) 1)
|
||||
Fixing pointer array-indexing *((word*) main::SCREEN + (number) 1)
|
||||
Created struct value member variable (word*) main::info_values
|
||||
Converted struct value to member variables (struct RadixInfo) main::info
|
||||
Adding struct value list initializer (word*) main::info_values ← (word[]) RADIX_DECIMAL_VALUES
|
||||
Replacing struct member reference (struct RadixInfo) main::info.values with member variable reference (word*) main::info_values
|
||||
Culled Empty Block (label) main::@4
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -11,31 +13,14 @@ CONTROL FLOW GRAPH SSA
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(word*) main::SCREEN#0 ← ((word*)) (number) $400
|
||||
(byte) main::radix#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
(byte) main::radix#4 ← phi( main/(byte) main::radix#0 main::@3/(byte) main::radix#1 )
|
||||
(word*) main::info_values#0 ← (word[]) RADIX_DECIMAL_VALUES#0
|
||||
(byte) main::digit#0 ← (byte) 0
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1 main::@2
|
||||
(byte) main::radix#3 ← phi( main::@1/(byte) main::radix#4 main::@2/(byte) main::radix#3 )
|
||||
(byte) main::digit#2 ← phi( main::@1/(byte) main::digit#0 main::@2/(byte) main::digit#1 )
|
||||
(word*) main::info_values#1 ← phi( main::@1/(word*) main::info_values#0 main::@2/(word*) main::info_values#1 )
|
||||
(word) main::digit_value#0 ← *((word*) main::info_values#1 + (byte) main::digit#2)
|
||||
(byte~) main::$2 ← (byte) main::digit#2 * (const byte) SIZEOF_WORD
|
||||
*((word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0
|
||||
(byte) main::digit#1 ← (byte) main::digit#2 + rangenext(0,4)
|
||||
(bool~) main::$0 ← (byte) main::digit#1 != rangelast(0,4)
|
||||
if((bool~) main::$0) goto main::@2
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
(byte) main::radix#2 ← phi( main::@2/(byte) main::radix#3 )
|
||||
(byte) main::radix#1 ← (byte) main::radix#2 + rangenext(0,1)
|
||||
(bool~) main::$1 ← (byte) main::radix#1 != rangelast(0,1)
|
||||
if((bool~) main::$1) goto main::@1
|
||||
(number~) main::$0 ← (number) 1 * (const byte) SIZEOF_WORD
|
||||
(number~) main::$1 ← (number) 0 * (const byte) SIZEOF_WORD
|
||||
*((word*) main::SCREEN#0 + (number~) main::$1) ← *((word*) main::info_values#0 + (number~) main::$0)
|
||||
(number~) main::$2 ← (number) 1 * (const byte) SIZEOF_WORD
|
||||
*((word*) main::SCREEN#0 + (number~) main::$2) ← *((word[]) RADIX_DECIMAL_VALUES#0 + (number~) main::$2)
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
@ -55,31 +40,22 @@ SYMBOL TABLE SSA
|
||||
(word*) RadixInfo::values
|
||||
(const byte) SIZEOF_WORD = (byte) 2
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(bool~) main::$1
|
||||
(byte~) main::$2
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(number~) main::$0
|
||||
(number~) main::$1
|
||||
(number~) main::$2
|
||||
(label) main::@return
|
||||
(word*) main::SCREEN
|
||||
(word*) main::SCREEN#0
|
||||
(byte) main::digit
|
||||
(byte) main::digit#0
|
||||
(byte) main::digit#1
|
||||
(byte) main::digit#2
|
||||
(word) main::digit_value
|
||||
(word) main::digit_value#0
|
||||
(word*) main::info_values
|
||||
(word*) main::info_values#0
|
||||
(word*) main::info_values#1
|
||||
(byte) main::radix
|
||||
(byte) main::radix#0
|
||||
(byte) main::radix#1
|
||||
(byte) main::radix#2
|
||||
(byte) main::radix#3
|
||||
(byte) main::radix#4
|
||||
|
||||
Adding number conversion cast (unumber) 1 in (number~) main::$0 ← (number) 1 * (const byte) SIZEOF_WORD
|
||||
Adding number conversion cast (unumber) main::$0 in (number~) main::$0 ← (unumber)(number) 1 * (const byte) SIZEOF_WORD
|
||||
Adding number conversion cast (unumber) 0 in (number~) main::$1 ← (number) 0 * (const byte) SIZEOF_WORD
|
||||
Adding number conversion cast (unumber) main::$1 in (number~) main::$1 ← (unumber)(number) 0 * (const byte) SIZEOF_WORD
|
||||
Adding number conversion cast (unumber) 1 in (number~) main::$2 ← (number) 1 * (const byte) SIZEOF_WORD
|
||||
Adding number conversion cast (unumber) main::$2 in (number~) main::$2 ← (unumber)(number) 1 * (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Adding number conversion cast (word) to elements in (word[]) RADIX_DECIMAL_VALUES#0 ← { (word)(number) $2710, (word)(number) $3e8, (word)(number) $64, (word)(number) $a }
|
||||
Successful SSA optimization PassNAddArrayNumberTypeConversions
|
||||
Inlining cast (word*) main::SCREEN#0 ← (word*)(number) $400
|
||||
@ -89,68 +65,57 @@ Simplifying constant integer cast $3e8
|
||||
Simplifying constant integer cast $64
|
||||
Simplifying constant integer cast $a
|
||||
Simplifying constant pointer cast (word*) 1024
|
||||
Simplifying constant integer cast 1
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant integer cast 1
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Alias (byte) main::radix#2 = (byte) main::radix#3
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Identical Phi Values (word*) main::info_values#1 (word*) main::info_values#0
|
||||
Identical Phi Values (byte) main::radix#2 (byte) main::radix#4
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) main::$0 [12] if((byte) main::digit#1!=rangelast(0,4)) goto main::@2
|
||||
Simple Condition (bool~) main::$1 [16] if((byte) main::radix#1!=rangelast(0,1)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Finalized unsigned number type (byte) 1
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) 1
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inferred type updated to byte in (unumber~) main::$0 ← (byte) 1 * (const byte) SIZEOF_WORD
|
||||
Inferred type updated to byte in (unumber~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Inferred type updated to byte in (unumber~) main::$2 ← (byte) 1 * (const byte) SIZEOF_WORD
|
||||
Constant right-side identified [0] (word[]) RADIX_DECIMAL_VALUES#0 ← { (word) $2710, (word) $3e8, (word) $64, (word) $a }
|
||||
Constant right-side identified [3] (byte~) main::$0 ← (byte) 1 * (const byte) SIZEOF_WORD
|
||||
Constant right-side identified [4] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Constant right-side identified [6] (byte~) main::$2 ← (byte) 1 * (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const word[]) RADIX_DECIMAL_VALUES#0 = { $2710, $3e8, $64, $a }
|
||||
Constant (const word*) main::SCREEN#0 = (word*) 1024
|
||||
Constant (const byte) main::radix#0 = 0
|
||||
Constant (const byte) main::digit#0 = 0
|
||||
Constant (const byte) main::$0 = 1*SIZEOF_WORD
|
||||
Constant (const byte) main::$1 = 0*SIZEOF_WORD
|
||||
Constant (const byte) main::$2 = 1*SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const word*) main::info_values#0 = RADIX_DECIMAL_VALUES#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [10] main::digit#1 ← ++ main::digit#2 to ++
|
||||
Resolved ranged comparison value [12] if(main::digit#1!=rangelast(0,4)) goto main::@2 to (number) 5
|
||||
Resolved ranged next value [14] main::radix#1 ← ++ main::radix#4 to ++
|
||||
Resolved ranged comparison value [16] if(main::radix#1!=rangelast(0,1)) goto main::@1 to (number) 2
|
||||
Adding number conversion cast (unumber) 5 in if((byte) main::digit#1!=(number) 5) goto main::@2
|
||||
Adding number conversion cast (unumber) 2 in if((byte) main::radix#1!=(number) 2) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant integer cast 5
|
||||
Simplifying constant integer cast 2
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 5
|
||||
Finalized unsigned number type (byte) 2
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Rewriting multiplication to use shift [3] (byte~) main::$2 ← (byte) main::digit#2 * (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2MultiplyToShiftRewriting
|
||||
Inlining constant with var siblings (const byte) main::radix#0
|
||||
Inlining constant with var siblings (const byte) main::digit#0
|
||||
Constant inlined main::info_values#0 = (const word[]) RADIX_DECIMAL_VALUES#0
|
||||
Constant inlined main::radix#0 = (byte) 0
|
||||
Constant inlined main::digit#0 = (byte) 0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Eliminating unused constant (const byte) SIZEOF_WORD
|
||||
Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_WORD in
|
||||
Successful SSA optimization PassNSimplifyConstantZero
|
||||
Simplifying expression containing zero main::SCREEN#0 in [5] *((const word*) main::SCREEN#0 + (const byte) main::$1) ← *((const word*) main::info_values#0 + (const byte) main::$0)
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) main::$1
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Added new block during phi lifting main::@5(between main::@3 and main::@1)
|
||||
Added new block during phi lifting main::@6(between main::@2 and main::@2)
|
||||
Constant inlined main::info_values#0 = (const word[]) RADIX_DECIMAL_VALUES#0
|
||||
Constant inlined main::$2 = (byte) 1*(const byte) SIZEOF_WORD
|
||||
Constant inlined main::$0 = (byte) 1*(const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Consolidated array index constant in *(RADIX_DECIMAL_VALUES#0+1*SIZEOF_WORD)
|
||||
Consolidated array index constant in *(RADIX_DECIMAL_VALUES#0+1*SIZEOF_WORD)
|
||||
Consolidated array index constant in *(main::SCREEN#0+1*SIZEOF_WORD)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced [16] main::radix#5 ← main::radix#1
|
||||
Coalesced [17] main::digit#3 ← main::digit#1
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Culled Empty Block (label) @2
|
||||
Culled Empty Block (label) main::@5
|
||||
Culled Empty Block (label) main::@6
|
||||
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
|
||||
@ -163,25 +128,11 @@ FINAL CONTROL FLOW GRAPH
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (byte) main::radix#4 ← phi( main/(byte) 0 main::@3/(byte) main::radix#1 )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1 main::@2
|
||||
[6] (byte) main::digit#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::digit#1 )
|
||||
[7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2)
|
||||
[8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1
|
||||
[9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0
|
||||
[10] (byte) main::digit#1 ← ++ (byte) main::digit#2
|
||||
[11] if((byte) main::digit#1!=(byte) 5) goto main::@2
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
[12] (byte) main::radix#1 ← ++ (byte) main::radix#4
|
||||
[13] if((byte) main::radix#1!=(byte) 2) goto main::@1
|
||||
[4] *((const word*) main::SCREEN#0) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD)
|
||||
[5] *((const word*) main::SCREEN#0+(byte) 1*(const byte) SIZEOF_WORD) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD)
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[14] return
|
||||
main::@return: scope:[main] from main
|
||||
[6] return
|
||||
to:@return
|
||||
|
||||
|
||||
@ -189,32 +140,11 @@ VARIABLE REGISTER WEIGHTS
|
||||
(word[]) RADIX_DECIMAL_VALUES
|
||||
(word*) RadixInfo::values
|
||||
(void()) main()
|
||||
(byte~) main::$2 202.0
|
||||
(word*) main::SCREEN
|
||||
(byte) main::digit
|
||||
(byte) main::digit#1 151.5
|
||||
(byte) main::digit#2 101.0
|
||||
(word) main::digit_value
|
||||
(word) main::digit_value#0 101.0
|
||||
(word*) main::info_values
|
||||
(byte) main::radix
|
||||
(byte) main::radix#1 16.5
|
||||
(byte) main::radix#4 3.142857142857143
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::radix#4 main::radix#1 ]
|
||||
[ main::digit#2 main::digit#1 ]
|
||||
Added variable main::digit_value#0 to zero page equivalence class [ main::digit_value#0 ]
|
||||
Added variable main::$2 to zero page equivalence class [ main::$2 ]
|
||||
Complete equivalence classes
|
||||
[ main::radix#4 main::radix#1 ]
|
||||
[ main::digit#2 main::digit#1 ]
|
||||
[ main::digit_value#0 ]
|
||||
[ main::$2 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
Allocated zp ZP_BYTE:3 [ main::digit#2 main::digit#1 ]
|
||||
Allocated zp ZP_WORD:4 [ main::digit_value#0 ]
|
||||
Allocated zp ZP_BYTE:6 [ main::$2 ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic
|
||||
@ -225,6 +155,7 @@ Target platform is c64basic
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
// @begin
|
||||
bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
@ -233,8 +164,6 @@ b1_from_bbegin:
|
||||
// @1
|
||||
b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
@ -244,99 +173,37 @@ bend:
|
||||
// main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label _2 = 6
|
||||
.label digit_value = 4
|
||||
.label digit = 3
|
||||
.label radix = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
// [5] phi (byte) main::radix#4 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta radix
|
||||
jmp b1
|
||||
// [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
|
||||
b1_from_b3:
|
||||
// [5] phi (byte) main::radix#4 = (byte) main::radix#1 [phi:main::@3->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
// main::@1
|
||||
b1:
|
||||
// [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
||||
b2_from_b1:
|
||||
// [6] phi (byte) main::digit#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta digit
|
||||
jmp b2
|
||||
// [6] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
|
||||
b2_from_b2:
|
||||
// [6] phi (byte) main::digit#2 = (byte) main::digit#1 [phi:main::@2->main::@2#0] -- register_copy
|
||||
jmp b2
|
||||
// main::@2
|
||||
b2:
|
||||
// [7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2) -- vwuz1=pwuc1_derefidx_vbuz2
|
||||
ldy digit
|
||||
lda RADIX_DECIMAL_VALUES,y
|
||||
sta digit_value
|
||||
lda RADIX_DECIMAL_VALUES+1,y
|
||||
sta digit_value+1
|
||||
// [8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1 -- vbuz1=vbuz2_rol_1
|
||||
lda digit
|
||||
asl
|
||||
sta _2
|
||||
// [9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0 -- pwuc1_derefidx_vbuz1=vwuz2
|
||||
ldy _2
|
||||
lda digit_value
|
||||
sta SCREEN,y
|
||||
lda digit_value+1
|
||||
sta SCREEN+1,y
|
||||
// [10] (byte) main::digit#1 ← ++ (byte) main::digit#2 -- vbuz1=_inc_vbuz1
|
||||
inc digit
|
||||
// [11] if((byte) main::digit#1!=(byte) 5) goto main::@2 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #5
|
||||
cmp digit
|
||||
bne b2_from_b2
|
||||
jmp b3
|
||||
// main::@3
|
||||
b3:
|
||||
// [12] (byte) main::radix#1 ← ++ (byte) main::radix#4 -- vbuz1=_inc_vbuz1
|
||||
inc radix
|
||||
// [13] if((byte) main::radix#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #2
|
||||
cmp radix
|
||||
bne b1_from_b3
|
||||
// [4] *((const word*) main::SCREEN#0) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) -- _deref_pwuc1=_deref_pwuc2
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1
|
||||
// [5] *((const word*) main::SCREEN#0+(byte) 1*(const byte) SIZEOF_WORD) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) -- _deref_pwuc1=_deref_pwuc2
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN+1*SIZEOF_WORD
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1*SIZEOF_WORD+1
|
||||
jmp breturn
|
||||
// main::@return
|
||||
breturn:
|
||||
// [14] return
|
||||
// [6] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
RADIX_DECIMAL_VALUES: .word $2710, $3e8, $64, $a
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2) [ main::radix#4 main::digit#2 main::digit_value#0 ] ( main:2 [ main::radix#4 main::digit#2 main::digit_value#0 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::digit#2 main::digit#1 ]
|
||||
Statement [8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1 [ main::radix#4 main::digit#2 main::digit_value#0 main::$2 ] ( main:2 [ main::radix#4 main::digit#2 main::digit_value#0 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0 [ main::radix#4 main::digit#2 ] ( main:2 [ main::radix#4 main::digit#2 ] ) always clobbers reg byte a
|
||||
Statement [7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2) [ main::radix#4 main::digit#2 main::digit_value#0 ] ( main:2 [ main::radix#4 main::digit#2 main::digit_value#0 ] ) always clobbers reg byte a
|
||||
Statement [8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1 [ main::radix#4 main::digit#2 main::digit_value#0 main::$2 ] ( main:2 [ main::radix#4 main::digit#2 main::digit_value#0 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0 [ main::radix#4 main::digit#2 ] ( main:2 [ main::radix#4 main::digit#2 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:3 [ main::digit#2 main::digit#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_WORD:4 [ main::digit_value#0 ] : zp ZP_WORD:4 ,
|
||||
Potential registers zp ZP_BYTE:6 [ main::$2 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y ,
|
||||
Statement [4] *((const word*) main::SCREEN#0) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [5] *((const word*) main::SCREEN#0+(byte) 1*(const byte) SIZEOF_WORD) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 252.5: zp ZP_BYTE:3 [ main::digit#2 main::digit#1 ] 202: zp ZP_BYTE:6 [ main::$2 ] 101: zp ZP_WORD:4 [ main::digit_value#0 ] 19.64: zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
Uplift Scope [RadixInfo]
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 5733 combination reg byte x [ main::digit#2 main::digit#1 ] reg byte a [ main::$2 ] zp ZP_WORD:4 [ main::digit_value#0 ] zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
Uplifting [RadixInfo] best 5733 combination
|
||||
Uplifting [] best 5733 combination
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
Uplifting [main] best 5733 combination zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
Allocated (was zp ZP_WORD:4) zp ZP_WORD:3 [ main::digit_value#0 ]
|
||||
Uplifting [RadixInfo] best 53 combination
|
||||
Uplifting [main] best 53 combination
|
||||
Uplifting [] best 53 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -346,6 +213,7 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
// @begin
|
||||
bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
@ -354,8 +222,6 @@ b1_from_bbegin:
|
||||
// @1
|
||||
b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
@ -365,63 +231,20 @@ bend:
|
||||
// main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label digit_value = 3
|
||||
.label radix = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
// [5] phi (byte) main::radix#4 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta radix
|
||||
jmp b1
|
||||
// [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
|
||||
b1_from_b3:
|
||||
// [5] phi (byte) main::radix#4 = (byte) main::radix#1 [phi:main::@3->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
// main::@1
|
||||
b1:
|
||||
// [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
||||
b2_from_b1:
|
||||
// [6] phi (byte) main::digit#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp b2
|
||||
// [6] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
|
||||
b2_from_b2:
|
||||
// [6] phi (byte) main::digit#2 = (byte) main::digit#1 [phi:main::@2->main::@2#0] -- register_copy
|
||||
jmp b2
|
||||
// main::@2
|
||||
b2:
|
||||
// [7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2) -- vwuz1=pwuc1_derefidx_vbuxx
|
||||
lda RADIX_DECIMAL_VALUES,x
|
||||
sta digit_value
|
||||
lda RADIX_DECIMAL_VALUES+1,x
|
||||
sta digit_value+1
|
||||
// [8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1 -- vbuaa=vbuxx_rol_1
|
||||
txa
|
||||
asl
|
||||
// [9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0 -- pwuc1_derefidx_vbuaa=vwuz1
|
||||
tay
|
||||
lda digit_value
|
||||
sta SCREEN,y
|
||||
lda digit_value+1
|
||||
sta SCREEN+1,y
|
||||
// [10] (byte) main::digit#1 ← ++ (byte) main::digit#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [11] if((byte) main::digit#1!=(byte) 5) goto main::@2 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #5
|
||||
bne b2_from_b2
|
||||
jmp b3
|
||||
// main::@3
|
||||
b3:
|
||||
// [12] (byte) main::radix#1 ← ++ (byte) main::radix#4 -- vbuz1=_inc_vbuz1
|
||||
inc radix
|
||||
// [13] if((byte) main::radix#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #2
|
||||
cmp radix
|
||||
bne b1_from_b3
|
||||
// [4] *((const word*) main::SCREEN#0) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) -- _deref_pwuc1=_deref_pwuc2
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1
|
||||
// [5] *((const word*) main::SCREEN#0+(byte) 1*(const byte) SIZEOF_WORD) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) -- _deref_pwuc1=_deref_pwuc2
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN+1*SIZEOF_WORD
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1*SIZEOF_WORD+1
|
||||
jmp breturn
|
||||
// main::@return
|
||||
breturn:
|
||||
// [14] return
|
||||
// [6] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -430,32 +253,18 @@ main: {
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp b3
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label b2_from_b2 with b2
|
||||
Replacing label b1_from_b3 with b1
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Removing instruction b1_from_b3:
|
||||
Removing instruction b2_from_b1:
|
||||
Removing instruction b2_from_b2:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction b1_from_main:
|
||||
Removing instruction b3:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
@ -466,32 +275,17 @@ FINAL SYMBOL TABLE
|
||||
(word[]) RADIX_DECIMAL_VALUES
|
||||
(const word[]) RADIX_DECIMAL_VALUES#0 RADIX_DECIMAL_VALUES = { (word) $2710, (word) $3e8, (word) $64, (word) $a }
|
||||
(word*) RadixInfo::values
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||
(void()) main()
|
||||
(byte~) main::$2 reg byte a 202.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@return
|
||||
(word*) main::SCREEN
|
||||
(const word*) main::SCREEN#0 SCREEN = (word*) 1024
|
||||
(byte) main::digit
|
||||
(byte) main::digit#1 reg byte x 151.5
|
||||
(byte) main::digit#2 reg byte x 101.0
|
||||
(word) main::digit_value
|
||||
(word) main::digit_value#0 digit_value zp ZP_WORD:3 101.0
|
||||
(word*) main::info_values
|
||||
(byte) main::radix
|
||||
(byte) main::radix#1 radix zp ZP_BYTE:2 16.5
|
||||
(byte) main::radix#4 radix zp ZP_BYTE:2 3.142857142857143
|
||||
|
||||
zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
reg byte x [ main::digit#2 main::digit#1 ]
|
||||
zp ZP_WORD:3 [ main::digit_value#0 ]
|
||||
reg byte a [ main::$2 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 4731
|
||||
Score: 38
|
||||
|
||||
// File Comments
|
||||
// Illustrates a problem with pointer sizeof()-rewriting for pointers inside structs
|
||||
@ -500,66 +294,31 @@ Score: 4731
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
// @1
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label digit_value = 3
|
||||
.label radix = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
// [5] phi (byte) main::radix#4 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta radix
|
||||
// [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
|
||||
// [5] phi (byte) main::radix#4 = (byte) main::radix#1 [phi:main::@3->main::@1#0] -- register_copy
|
||||
// main::@1
|
||||
b1:
|
||||
// [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
||||
// [6] phi (byte) main::digit#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
// [6] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
|
||||
// [6] phi (byte) main::digit#2 = (byte) main::digit#1 [phi:main::@2->main::@2#0] -- register_copy
|
||||
// main::@2
|
||||
b2:
|
||||
// digit_value = info.values[digit]
|
||||
// [7] (word) main::digit_value#0 ← *((const word[]) RADIX_DECIMAL_VALUES#0 + (byte) main::digit#2) -- vwuz1=pwuc1_derefidx_vbuxx
|
||||
lda RADIX_DECIMAL_VALUES,x
|
||||
sta digit_value
|
||||
lda RADIX_DECIMAL_VALUES+1,x
|
||||
sta digit_value+1
|
||||
// SCREEN[digit] = digit_value
|
||||
// [8] (byte~) main::$2 ← (byte) main::digit#2 << (byte) 1 -- vbuaa=vbuxx_rol_1
|
||||
txa
|
||||
asl
|
||||
// [9] *((const word*) main::SCREEN#0 + (byte~) main::$2) ← (word) main::digit_value#0 -- pwuc1_derefidx_vbuaa=vwuz1
|
||||
tay
|
||||
lda digit_value
|
||||
sta SCREEN,y
|
||||
lda digit_value+1
|
||||
sta SCREEN+1,y
|
||||
// for( char digit: 0..4 )
|
||||
// [10] (byte) main::digit#1 ← ++ (byte) main::digit#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [11] if((byte) main::digit#1!=(byte) 5) goto main::@2 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #5
|
||||
bne b2
|
||||
// main::@3
|
||||
// for( byte radix: 0..1)
|
||||
// [12] (byte) main::radix#1 ← ++ (byte) main::radix#4 -- vbuz1=_inc_vbuz1
|
||||
inc radix
|
||||
// [13] if((byte) main::radix#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #2
|
||||
cmp radix
|
||||
bne b1
|
||||
// SCREEN[0] = info.values[1]
|
||||
// [4] *((const word*) main::SCREEN#0) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) -- _deref_pwuc1=_deref_pwuc2
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1
|
||||
// SCREEN[1] = RADIX_DECIMAL_VALUES[1]
|
||||
// [5] *((const word*) main::SCREEN#0+(byte) 1*(const byte) SIZEOF_WORD) ← *((const word[]) RADIX_DECIMAL_VALUES#0+(byte) 1*(const byte) SIZEOF_WORD) -- _deref_pwuc1=_deref_pwuc2
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD
|
||||
sta SCREEN+1*SIZEOF_WORD
|
||||
lda RADIX_DECIMAL_VALUES+1*SIZEOF_WORD+1
|
||||
sta SCREEN+1*SIZEOF_WORD+1
|
||||
// main::@return
|
||||
// }
|
||||
// [14] return
|
||||
// [6] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -4,25 +4,10 @@
|
||||
(word[]) RADIX_DECIMAL_VALUES
|
||||
(const word[]) RADIX_DECIMAL_VALUES#0 RADIX_DECIMAL_VALUES = { (word) $2710, (word) $3e8, (word) $64, (word) $a }
|
||||
(word*) RadixInfo::values
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||
(void()) main()
|
||||
(byte~) main::$2 reg byte a 202.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@return
|
||||
(word*) main::SCREEN
|
||||
(const word*) main::SCREEN#0 SCREEN = (word*) 1024
|
||||
(byte) main::digit
|
||||
(byte) main::digit#1 reg byte x 151.5
|
||||
(byte) main::digit#2 reg byte x 101.0
|
||||
(word) main::digit_value
|
||||
(word) main::digit_value#0 digit_value zp ZP_WORD:3 101.0
|
||||
(word*) main::info_values
|
||||
(byte) main::radix
|
||||
(byte) main::radix#1 radix zp ZP_BYTE:2 16.5
|
||||
(byte) main::radix#4 radix zp ZP_BYTE:2 3.142857142857143
|
||||
|
||||
zp ZP_BYTE:2 [ main::radix#4 main::radix#1 ]
|
||||
reg byte x [ main::digit#2 main::digit#1 ]
|
||||
zp ZP_WORD:3 [ main::digit_value#0 ]
|
||||
reg byte a [ main::$2 ]
|
||||
|
Loading…
Reference in New Issue
Block a user