mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-02 05:30:53 +00:00
Implemented pointer math (+/-) fixing
This commit is contained in:
parent
85317a1c5e
commit
287a6ecb2e
4
src/main/fragment/vwuz1=_deref_pwuc1.asm
Normal file
4
src/main/fragment/vwuz1=_deref_pwuc1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
lda {c1}+1
|
||||
sta {z1}+1
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
|
||||
@ -7,7 +8,10 @@ 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.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.ListIterator;
|
||||
@ -30,28 +34,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if((assignment.getrValue1() == null) && (assignment.getOperator() != null) && (assignment.getrValue2() instanceof VariableRef)) {
|
||||
// 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();
|
||||
if(pointerType.getElementType().getSizeBytes() > 1) {
|
||||
// Unary operation on non-byte pointer type - sizeof()-handling is needed!
|
||||
if(Operators.INCREMENT.equals(assignment.getOperator())) {
|
||||
// Pointer increment - add sizeof(type) instead
|
||||
getLog().append("Fixing pointer increment " + statement.toString(getProgram(), false));
|
||||
assignment.setrValue1(assignment.getrValue2());
|
||||
assignment.setOperator(Operators.PLUS);
|
||||
assignment.setrValue2(OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType()));
|
||||
} else if(Operators.DECREMENT.equals(assignment.getOperator())) {
|
||||
// Pointer Decrement - add sizeof(type) instead
|
||||
getLog().append("Fixing pointer decrement " + statement.toString(getProgram(), false));
|
||||
assignment.setrValue1(assignment.getrValue2());
|
||||
assignment.setOperator(Operators.MINUS);
|
||||
assignment.setrValue2(OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
fixPointerUnary(assignment);
|
||||
} else if((assignment.getrValue1() instanceof VariableRef) && (assignment.getOperator() != null) && (assignment.getrValue2() != null)) {
|
||||
fixPointerBinary(block, stmtIt, assignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,5 +44,63 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine if the binary operation in the assignment is a pointer operation - and fix it to reflect sizeof()
|
||||
*
|
||||
* @param assignment The assignment statement
|
||||
*/
|
||||
|
||||
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();
|
||||
if(pointerType.getElementType().getSizeBytes() > 1) {
|
||||
// Binary operation on a non-byte pointer - sizeof()-handling is probably needed!
|
||||
if(Operators.PLUS.equals(assignment.getOperator()) || Operators.MINUS.equals(assignment.getOperator())) {
|
||||
// Adding to a pointer - multiply by sizeof()
|
||||
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
|
||||
VariableIntermediate tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
|
||||
tmpVar.setType(SymbolType.BYTE);
|
||||
stmtIt.remove();
|
||||
ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
stmtIt.add(new StatementAssignment(tmpVar.getRef(), assignment.getrValue2(), Operators.MULTIPLY, sizeOfTargetType, assignment.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(assignment);
|
||||
assignment.setrValue2(tmpVar.getRef());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine if the unary operation in the assignment is a pointer operation - and fix it to reflect sizeof()
|
||||
*
|
||||
* @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();
|
||||
if(pointerType.getElementType().getSizeBytes() > 1) {
|
||||
// Unary operation on non-byte pointer type - sizeof()-handling is needed!
|
||||
if(Operators.INCREMENT.equals(assignment.getOperator())) {
|
||||
// Pointer increment - add sizeof(type) instead
|
||||
getLog().append("Fixing pointer increment " + assignment.toString(getProgram(), false));
|
||||
assignment.setrValue1(assignment.getrValue2());
|
||||
assignment.setOperator(Operators.PLUS);
|
||||
assignment.setrValue2(OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType()));
|
||||
} else if(Operators.DECREMENT.equals(assignment.getOperator())) {
|
||||
// Pointer Decrement - add sizeof(type) instead
|
||||
getLog().append("Fixing pointer decrement " + assignment.toString(getProgram(), false));
|
||||
assignment.setrValue1(assignment.getrValue2());
|
||||
assignment.setOperator(Operators.MINUS);
|
||||
assignment.setrValue2(OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ public class TestPrograms {
|
||||
compileAndCompare("word-pointer-math");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordPointerMath0() throws IOException, URISyntaxException {
|
||||
compileAndCompare("word-pointer-math-0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordPointerIteration() throws IOException, URISyntaxException {
|
||||
compileAndCompare("word-pointer-iteration");
|
||||
|
11
src/test/kc/word-pointer-math-0.kc
Normal file
11
src/test/kc/word-pointer-math-0.kc
Normal file
@ -0,0 +1,11 @@
|
||||
// Tests simple word pointer math
|
||||
void main() {
|
||||
word* words = $0400;
|
||||
const byte* SCREEN = $400+6*40;
|
||||
word w1 = *(words+1);
|
||||
SCREEN[0] = <w1;
|
||||
SCREEN[1] = >w1;
|
||||
word w2 = *(words+2);
|
||||
SCREEN[2] = <w2;
|
||||
SCREEN[3] = >w2;
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_WORD = 2
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label w = 5
|
||||
@ -21,8 +22,11 @@ main: {
|
||||
iny
|
||||
lda (wp),y
|
||||
sta w+1
|
||||
inc wp
|
||||
bne !+
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc wp
|
||||
sta wp
|
||||
bcc !+
|
||||
inc wp+1
|
||||
!:
|
||||
lda w
|
||||
|
@ -15,7 +15,7 @@ main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::idx#4 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::idx#3 )
|
||||
[5] (word*) main::wp#2 ← phi( main/(const word[]) main::words#0 main::@1/(word*) main::wp#1 )
|
||||
[6] (word) main::w#0 ← *((word*) main::wp#2)
|
||||
[7] (word*) main::wp#1 ← ++ (word*) main::wp#2
|
||||
[7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD
|
||||
[8] (byte~) main::$0 ← < (word) main::w#0
|
||||
[9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$0
|
||||
[10] (byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
|
@ -1,3 +1,4 @@
|
||||
Fixing pointer increment (word*) main::wp ← ++ (word*) main::wp
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -14,7 +15,7 @@ main::@1: scope:[main] from main main::@1
|
||||
(byte) main::idx#4 ← phi( main/(byte) main::idx#0 main::@1/(byte) main::idx#3 )
|
||||
(word*) main::wp#2 ← phi( main/(word*) main::wp#0 main::@1/(word*) main::wp#1 )
|
||||
(word) main::w#0 ← *((word*) main::wp#2)
|
||||
(word*) main::wp#1 ← ++ (word*) main::wp#2
|
||||
(word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD
|
||||
(byte~) main::$0 ← < (word) main::w#0
|
||||
*((byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$0
|
||||
(byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
@ -41,6 +42,7 @@ SYMBOL TABLE SSA
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte~) main::$0
|
||||
(byte~) main::$1
|
||||
@ -123,7 +125,7 @@ main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::idx#4 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::idx#3 )
|
||||
[5] (word*) main::wp#2 ← phi( main/(const word[]) main::words#0 main::@1/(word*) main::wp#1 )
|
||||
[6] (word) main::w#0 ← *((word*) main::wp#2)
|
||||
[7] (word*) main::wp#1 ← ++ (word*) main::wp#2
|
||||
[7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD
|
||||
[8] (byte~) main::$0 ← < (word) main::w#0
|
||||
[9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$0
|
||||
[10] (byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
@ -194,6 +196,7 @@ INITIAL ASM
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
@ -251,9 +254,12 @@ main: {
|
||||
iny
|
||||
lda (wp),y
|
||||
sta w+1
|
||||
//SEG21 [7] (word*) main::wp#1 ← ++ (word*) main::wp#2 -- pwuz1=_inc_pwuz1
|
||||
inc wp
|
||||
bne !+
|
||||
//SEG21 [7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD -- pwuz1=pwuz1_plus_vbuc1
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc wp
|
||||
sta wp
|
||||
bcc !+
|
||||
inc wp+1
|
||||
!:
|
||||
//SEG22 [8] (byte~) main::$0 ← < (word) main::w#0 -- vbuz1=_lo_vwuz2
|
||||
@ -303,10 +309,12 @@ Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ ma
|
||||
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:4 [ main::idx#4 main::idx#3 ]
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:5 [ main::i#2 main::i#1 ]
|
||||
Statement [7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD [ main::idx#4 main::i#2 main::wp#1 main::w#0 ] ( main:2 [ main::idx#4 main::i#2 main::wp#1 main::w#0 ] ) always clobbers reg byte a
|
||||
Statement [8] (byte~) main::$0 ← < (word) main::w#0 [ main::idx#4 main::i#2 main::wp#1 main::w#0 main::$0 ] ( main:2 [ main::idx#4 main::i#2 main::wp#1 main::w#0 main::$0 ] ) always clobbers reg byte a
|
||||
Statement [11] (byte~) main::$1 ← > (word) main::w#0 [ main::i#2 main::wp#1 main::idx#1 main::$1 ] ( main:2 [ main::i#2 main::wp#1 main::idx#1 main::$1 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:9 [ main::idx#1 ]
|
||||
Statement [6] (word) main::w#0 ← *((word*) main::wp#2) [ main::wp#2 main::idx#4 main::i#2 main::w#0 ] ( main:2 [ main::wp#2 main::idx#4 main::i#2 main::w#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD [ main::idx#4 main::i#2 main::wp#1 main::w#0 ] ( main:2 [ main::idx#4 main::i#2 main::wp#1 main::w#0 ] ) always clobbers reg byte a
|
||||
Statement [8] (byte~) main::$0 ← < (word) main::w#0 [ main::idx#4 main::i#2 main::wp#1 main::w#0 main::$0 ] ( main:2 [ main::idx#4 main::i#2 main::wp#1 main::w#0 main::$0 ] ) always clobbers reg byte a
|
||||
Statement [11] (byte~) main::$1 ← > (word) main::w#0 [ main::i#2 main::wp#1 main::idx#1 main::$1 ] ( main:2 [ main::i#2 main::wp#1 main::idx#1 main::$1 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_WORD:2 [ main::wp#2 main::wp#1 ] : zp ZP_WORD:2 ,
|
||||
@ -322,13 +330,13 @@ REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 22: zp ZP_BYTE:8 [ main::$0 ] 22: zp ZP_BYTE:10 [ main::$1 ] 22: zp ZP_BYTE:11 [ main::idx#2 ] 18.7: zp ZP_WORD:2 [ main::wp#2 main::wp#1 ] 18.7: zp ZP_BYTE:5 [ main::i#2 main::i#1 ] 13.93: zp ZP_BYTE:4 [ main::idx#4 main::idx#3 ] 11: zp ZP_BYTE:9 [ main::idx#1 ] 6.6: zp ZP_WORD:6 [ main::w#0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 1118 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ] reg byte a [ main::idx#2 ] zp ZP_WORD:2 [ main::wp#2 main::wp#1 ] reg byte x [ main::i#2 main::i#1 ] zp ZP_BYTE:4 [ main::idx#4 main::idx#3 ] zp ZP_BYTE:9 [ main::idx#1 ] zp ZP_WORD:6 [ main::w#0 ]
|
||||
Uplifting [main] best 1168 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ] reg byte a [ main::idx#2 ] zp ZP_WORD:2 [ main::wp#2 main::wp#1 ] reg byte x [ main::i#2 main::i#1 ] zp ZP_BYTE:4 [ main::idx#4 main::idx#3 ] zp ZP_BYTE:9 [ main::idx#1 ] zp ZP_WORD:6 [ main::w#0 ]
|
||||
Limited combination testing to 100 combinations of 768 possible.
|
||||
Uplifting [] best 1118 combination
|
||||
Uplifting [] best 1168 combination
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:4 [ main::idx#4 main::idx#3 ]
|
||||
Uplifting [main] best 1118 combination zp ZP_BYTE:4 [ main::idx#4 main::idx#3 ]
|
||||
Uplifting [main] best 1168 combination zp ZP_BYTE:4 [ main::idx#4 main::idx#3 ]
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:9 [ main::idx#1 ]
|
||||
Uplifting [main] best 1028 combination reg byte y [ main::idx#1 ]
|
||||
Uplifting [main] best 1078 combination reg byte y [ main::idx#1 ]
|
||||
Allocated (was zp ZP_WORD:6) zp ZP_WORD:5 [ main::w#0 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
@ -339,6 +347,7 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
@ -389,9 +398,12 @@ main: {
|
||||
iny
|
||||
lda (wp),y
|
||||
sta w+1
|
||||
//SEG21 [7] (word*) main::wp#1 ← ++ (word*) main::wp#2 -- pwuz1=_inc_pwuz1
|
||||
inc wp
|
||||
bne !+
|
||||
//SEG21 [7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD -- pwuz1=pwuz1_plus_vbuc1
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc wp
|
||||
sta wp
|
||||
bcc !+
|
||||
inc wp+1
|
||||
!:
|
||||
//SEG22 [8] (byte~) main::$0 ← < (word) main::w#0 -- vbuaa=_lo_vwuz1
|
||||
@ -459,6 +471,7 @@ FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 22.0
|
||||
(byte~) main::$1 reg byte a 22.0
|
||||
@ -493,7 +506,7 @@ reg byte a [ main::idx#2 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 896
|
||||
Score: 946
|
||||
|
||||
//SEG0 File Comments
|
||||
// Tests simple word pointer iteration
|
||||
@ -502,6 +515,7 @@ Score: 896
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
@ -539,9 +553,12 @@ main: {
|
||||
iny
|
||||
lda (wp),y
|
||||
sta w+1
|
||||
//SEG21 [7] (word*) main::wp#1 ← ++ (word*) main::wp#2 -- pwuz1=_inc_pwuz1
|
||||
inc wp
|
||||
bne !+
|
||||
//SEG21 [7] (word*) main::wp#1 ← (word*) main::wp#2 + (const byte) SIZEOF_WORD -- pwuz1=pwuz1_plus_vbuc1
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc wp
|
||||
sta wp
|
||||
bcc !+
|
||||
inc wp+1
|
||||
!:
|
||||
//SEG22 [8] (byte~) main::$0 ← < (word) main::w#0 -- vbuaa=_lo_vwuz1
|
||||
|
@ -1,6 +1,7 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 22.0
|
||||
(byte~) main::$1 reg byte a 22.0
|
||||
|
28
src/test/ref/word-pointer-math-0.asm
Normal file
28
src/test/ref/word-pointer-math-0.asm
Normal file
@ -0,0 +1,28 @@
|
||||
// Tests simple word pointer math
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_WORD = 2
|
||||
main: {
|
||||
.label words = $400
|
||||
.label SCREEN = $400+6*$28
|
||||
.label w1 = 2
|
||||
.label w2 = 2
|
||||
lda words+1*SIZEOF_WORD
|
||||
sta w1
|
||||
lda words+1*SIZEOF_WORD+1
|
||||
sta w1+1
|
||||
lda w1
|
||||
sta SCREEN
|
||||
lda w1+1
|
||||
sta SCREEN+1
|
||||
lda words+2*SIZEOF_WORD
|
||||
sta w2
|
||||
lda words+2*SIZEOF_WORD+1
|
||||
sta w2+1
|
||||
lda w2
|
||||
sta SCREEN+2
|
||||
lda w2+1
|
||||
sta SCREEN+3
|
||||
rts
|
||||
}
|
24
src/test/ref/word-pointer-math-0.cfg
Normal file
24
src/test/ref/word-pointer-math-0.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] (word) main::w1#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD)
|
||||
[5] (byte~) main::$3 ← < (word) main::w1#0
|
||||
[6] *((const byte*) main::SCREEN#0) ← (byte~) main::$3
|
||||
[7] (byte~) main::$4 ← > (word) main::w1#0
|
||||
[8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4
|
||||
[9] (word) main::w2#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD)
|
||||
[10] (byte~) main::$6 ← < (word) main::w2#0
|
||||
[11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$6
|
||||
[12] (byte~) main::$7 ← > (word) main::w2#0
|
||||
[13] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$7
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[14] return
|
||||
to:@return
|
421
src/test/ref/word-pointer-math-0.log
Normal file
421
src/test/ref/word-pointer-math-0.log
Normal file
@ -0,0 +1,421 @@
|
||||
Fixing pointer addition (word*~) main::$2 ← (word*) main::words + (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
Fixing pointer addition (word*~) main::$5 ← (word*) main::words + (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
Identified constant variable (word*) main::words
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(word*) main::words#0 ← ((word*)) (word/signed word/dword/signed dword) $400
|
||||
(byte/word/signed word/dword/signed dword~) main::$0 ← (byte/signed byte/word/signed word/dword/signed dword) 6 * (byte/signed byte/word/signed word/dword/signed dword) $28
|
||||
(word/signed dword/dword/signed word~) main::$1 ← (word/signed word/dword/signed dword) $400 + (byte/word/signed word/dword/signed dword~) main::$0
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed dword/dword/signed word~) main::$1
|
||||
(byte) main::$8 ← (byte/signed byte/word/signed word/dword/signed dword) 1 * (const byte) SIZEOF_WORD
|
||||
(word*~) main::$2 ← (word*) main::words#0 + (byte) main::$8
|
||||
(word) main::w1#0 ← *((word*~) main::$2)
|
||||
(byte~) main::$3 ← < (word) main::w1#0
|
||||
*((byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte~) main::$3
|
||||
(byte~) main::$4 ← > (word) main::w1#0
|
||||
*((byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4
|
||||
(byte) main::$9 ← (byte/signed byte/word/signed word/dword/signed dword) 2 * (const byte) SIZEOF_WORD
|
||||
(word*~) main::$5 ← (word*) main::words#0 + (byte) main::$9
|
||||
(word) main::w2#0 ← *((word*~) main::$5)
|
||||
(byte~) main::$6 ← < (word) main::w2#0
|
||||
*((byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$6
|
||||
(byte~) main::$7 ← > (word) main::w2#0
|
||||
*((byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$7
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte/word/signed word/dword/signed dword~) main::$0
|
||||
(word/signed dword/dword/signed word~) main::$1
|
||||
(word*~) main::$2
|
||||
(byte~) main::$3
|
||||
(byte~) main::$4
|
||||
(word*~) main::$5
|
||||
(byte~) main::$6
|
||||
(byte~) main::$7
|
||||
(byte) main::$8
|
||||
(byte) main::$9
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte*) main::SCREEN#0
|
||||
(word) main::w1
|
||||
(word) main::w1#0
|
||||
(word) main::w2
|
||||
(word) main::w2#0
|
||||
(word*) main::words
|
||||
(word*) main::words#0
|
||||
|
||||
Culled Empty Block (label) @2
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Constant (const word*) main::words#0 = ((word*))$400
|
||||
Constant (const byte/word/signed word/dword/signed dword) main::$0 = 6*$28
|
||||
Constant (const byte) main::$8 = 1*SIZEOF_WORD
|
||||
Constant (const byte) main::$9 = 2*SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const word/signed dword/dword/signed word) main::$1 = $400+main::$0
|
||||
Constant (const word*) main::$2 = main::words#0+main::$8
|
||||
Constant (const word*) main::$5 = main::words#0+main::$9
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))main::$1
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+0)
|
||||
Consolidated array index constant in *(main::SCREEN#0+1)
|
||||
Consolidated array index constant in *(main::SCREEN#0+2)
|
||||
Consolidated array index constant in *(main::SCREEN#0+3)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Constant inlined main::$1 = (word/signed word/dword/signed dword) $400+(byte/signed byte/word/signed word/dword/signed dword) 6*(byte/signed byte/word/signed word/dword/signed dword) $28
|
||||
Constant inlined main::$2 = (const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD
|
||||
Constant inlined main::$0 = (byte/signed byte/word/signed word/dword/signed dword) 6*(byte/signed byte/word/signed word/dword/signed dword) $28
|
||||
Constant inlined main::$5 = (const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD
|
||||
Constant inlined main::$9 = (byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD
|
||||
Constant inlined main::$8 = (byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Simplifying constant plus zero main::SCREEN#0+0
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] (word) main::w1#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD)
|
||||
[5] (byte~) main::$3 ← < (word) main::w1#0
|
||||
[6] *((const byte*) main::SCREEN#0) ← (byte~) main::$3
|
||||
[7] (byte~) main::$4 ← > (word) main::w1#0
|
||||
[8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4
|
||||
[9] (word) main::w2#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD)
|
||||
[10] (byte~) main::$6 ← < (word) main::w2#0
|
||||
[11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$6
|
||||
[12] (byte~) main::$7 ← > (word) main::w2#0
|
||||
[13] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$7
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte~) main::$3 4.0
|
||||
(byte~) main::$4 4.0
|
||||
(byte~) main::$6 4.0
|
||||
(byte~) main::$7 4.0
|
||||
(byte*) main::SCREEN
|
||||
(word) main::w1
|
||||
(word) main::w1#0 2.0
|
||||
(word) main::w2
|
||||
(word) main::w2#0 2.0
|
||||
(word*) main::words
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::w1#0 to zero page equivalence class [ main::w1#0 ]
|
||||
Added variable main::$3 to zero page equivalence class [ main::$3 ]
|
||||
Added variable main::$4 to zero page equivalence class [ main::$4 ]
|
||||
Added variable main::w2#0 to zero page equivalence class [ main::w2#0 ]
|
||||
Added variable main::$6 to zero page equivalence class [ main::$6 ]
|
||||
Added variable main::$7 to zero page equivalence class [ main::$7 ]
|
||||
Complete equivalence classes
|
||||
[ main::w1#0 ]
|
||||
[ main::$3 ]
|
||||
[ main::$4 ]
|
||||
[ main::w2#0 ]
|
||||
[ main::$6 ]
|
||||
[ main::$7 ]
|
||||
Allocated zp ZP_WORD:2 [ main::w1#0 ]
|
||||
Allocated zp ZP_BYTE:4 [ main::$3 ]
|
||||
Allocated zp ZP_BYTE:5 [ main::$4 ]
|
||||
Allocated zp ZP_WORD:6 [ main::w2#0 ]
|
||||
Allocated zp ZP_BYTE:8 [ main::$6 ]
|
||||
Allocated zp ZP_BYTE:9 [ main::$7 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Tests simple word pointer math
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 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
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label words = $400
|
||||
.label SCREEN = $400+6*$28
|
||||
.label _3 = 4
|
||||
.label _4 = 5
|
||||
.label _6 = 8
|
||||
.label _7 = 9
|
||||
.label w1 = 2
|
||||
.label w2 = 6
|
||||
//SEG10 [4] (word) main::w1#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD) -- vwuz1=_deref_pwuc1
|
||||
lda words+1*SIZEOF_WORD
|
||||
sta w1
|
||||
lda words+1*SIZEOF_WORD+1
|
||||
sta w1+1
|
||||
//SEG11 [5] (byte~) main::$3 ← < (word) main::w1#0 -- vbuz1=_lo_vwuz2
|
||||
lda w1
|
||||
sta _3
|
||||
//SEG12 [6] *((const byte*) main::SCREEN#0) ← (byte~) main::$3 -- _deref_pbuc1=vbuz1
|
||||
lda _3
|
||||
sta SCREEN
|
||||
//SEG13 [7] (byte~) main::$4 ← > (word) main::w1#0 -- vbuz1=_hi_vwuz2
|
||||
lda w1+1
|
||||
sta _4
|
||||
//SEG14 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4 -- _deref_pbuc1=vbuz1
|
||||
lda _4
|
||||
sta SCREEN+1
|
||||
//SEG15 [9] (word) main::w2#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD) -- vwuz1=_deref_pwuc1
|
||||
lda words+2*SIZEOF_WORD
|
||||
sta w2
|
||||
lda words+2*SIZEOF_WORD+1
|
||||
sta w2+1
|
||||
//SEG16 [10] (byte~) main::$6 ← < (word) main::w2#0 -- vbuz1=_lo_vwuz2
|
||||
lda w2
|
||||
sta _6
|
||||
//SEG17 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$6 -- _deref_pbuc1=vbuz1
|
||||
lda _6
|
||||
sta SCREEN+2
|
||||
//SEG18 [12] (byte~) main::$7 ← > (word) main::w2#0 -- vbuz1=_hi_vwuz2
|
||||
lda w2+1
|
||||
sta _7
|
||||
//SEG19 [13] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$7 -- _deref_pbuc1=vbuz1
|
||||
lda _7
|
||||
sta SCREEN+3
|
||||
jmp breturn
|
||||
//SEG20 main::@return
|
||||
breturn:
|
||||
//SEG21 [14] return
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] (word) main::w1#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD) [ main::w1#0 ] ( main:2 [ main::w1#0 ] ) always clobbers reg byte a
|
||||
Statement [5] (byte~) main::$3 ← < (word) main::w1#0 [ main::w1#0 main::$3 ] ( main:2 [ main::w1#0 main::$3 ] ) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$4 ← > (word) main::w1#0 [ main::$4 ] ( main:2 [ main::$4 ] ) always clobbers reg byte a
|
||||
Statement [9] (word) main::w2#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD) [ main::w2#0 ] ( main:2 [ main::w2#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte~) main::$6 ← < (word) main::w2#0 [ main::w2#0 main::$6 ] ( main:2 [ main::w2#0 main::$6 ] ) always clobbers reg byte a
|
||||
Statement [12] (byte~) main::$7 ← > (word) main::w2#0 [ main::$7 ] ( main:2 [ main::$7 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_WORD:2 [ main::w1#0 ] : zp ZP_WORD:2 ,
|
||||
Potential registers zp ZP_BYTE:4 [ main::$3 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:5 [ main::$4 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_WORD:6 [ main::w2#0 ] : zp ZP_WORD:6 ,
|
||||
Potential registers zp ZP_BYTE:8 [ main::$6 ] : zp ZP_BYTE:8 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:9 [ main::$7 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 4: zp ZP_BYTE:4 [ main::$3 ] 4: zp ZP_BYTE:5 [ main::$4 ] 4: zp ZP_BYTE:8 [ main::$6 ] 4: zp ZP_BYTE:9 [ main::$7 ] 2: zp ZP_WORD:2 [ main::w1#0 ] 2: zp ZP_WORD:6 [ main::w2#0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 77 combination reg byte a [ main::$3 ] reg byte a [ main::$4 ] reg byte a [ main::$6 ] reg byte a [ main::$7 ] zp ZP_WORD:2 [ main::w1#0 ] zp ZP_WORD:6 [ main::w2#0 ]
|
||||
Limited combination testing to 100 combinations of 256 possible.
|
||||
Uplifting [] best 77 combination
|
||||
Coalescing zero page register [ zp ZP_WORD:2 [ main::w1#0 ] ] with [ zp ZP_WORD:6 [ main::w2#0 ] ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Tests simple word pointer math
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 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
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label words = $400
|
||||
.label SCREEN = $400+6*$28
|
||||
.label w1 = 2
|
||||
.label w2 = 2
|
||||
//SEG10 [4] (word) main::w1#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD) -- vwuz1=_deref_pwuc1
|
||||
lda words+1*SIZEOF_WORD
|
||||
sta w1
|
||||
lda words+1*SIZEOF_WORD+1
|
||||
sta w1+1
|
||||
//SEG11 [5] (byte~) main::$3 ← < (word) main::w1#0 -- vbuaa=_lo_vwuz1
|
||||
lda w1
|
||||
//SEG12 [6] *((const byte*) main::SCREEN#0) ← (byte~) main::$3 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
//SEG13 [7] (byte~) main::$4 ← > (word) main::w1#0 -- vbuaa=_hi_vwuz1
|
||||
lda w1+1
|
||||
//SEG14 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN+1
|
||||
//SEG15 [9] (word) main::w2#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD) -- vwuz1=_deref_pwuc1
|
||||
lda words+2*SIZEOF_WORD
|
||||
sta w2
|
||||
lda words+2*SIZEOF_WORD+1
|
||||
sta w2+1
|
||||
//SEG16 [10] (byte~) main::$6 ← < (word) main::w2#0 -- vbuaa=_lo_vwuz1
|
||||
lda w2
|
||||
//SEG17 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$6 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN+2
|
||||
//SEG18 [12] (byte~) main::$7 ← > (word) main::w2#0 -- vbuaa=_hi_vwuz1
|
||||
lda w2+1
|
||||
//SEG19 [13] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$7 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN+3
|
||||
jmp breturn
|
||||
//SEG20 main::@return
|
||||
breturn:
|
||||
//SEG21 [14] return
|
||||
rts
|
||||
}
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte~) main::$3 reg byte a 4.0
|
||||
(byte~) main::$4 reg byte a 4.0
|
||||
(byte~) main::$6 reg byte a 4.0
|
||||
(byte~) main::$7 reg byte a 4.0
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400+(byte/signed byte/word/signed word/dword/signed dword) 6*(byte/signed byte/word/signed word/dword/signed dword) $28
|
||||
(word) main::w1
|
||||
(word) main::w1#0 w1 zp ZP_WORD:2 2.0
|
||||
(word) main::w2
|
||||
(word) main::w2#0 w2 zp ZP_WORD:2 2.0
|
||||
(word*) main::words
|
||||
(const word*) main::words#0 words = ((word*))(word/signed word/dword/signed dword) $400
|
||||
|
||||
zp ZP_WORD:2 [ main::w1#0 main::w2#0 ]
|
||||
reg byte a [ main::$3 ]
|
||||
reg byte a [ main::$4 ]
|
||||
reg byte a [ main::$6 ]
|
||||
reg byte a [ main::$7 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 62
|
||||
|
||||
//SEG0 File Comments
|
||||
// Tests simple word pointer math
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG8 @end
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label words = $400
|
||||
.label SCREEN = $400+6*$28
|
||||
.label w1 = 2
|
||||
.label w2 = 2
|
||||
//SEG10 [4] (word) main::w1#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(const byte) SIZEOF_WORD) -- vwuz1=_deref_pwuc1
|
||||
lda words+1*SIZEOF_WORD
|
||||
sta w1
|
||||
lda words+1*SIZEOF_WORD+1
|
||||
sta w1+1
|
||||
//SEG11 [5] (byte~) main::$3 ← < (word) main::w1#0 -- vbuaa=_lo_vwuz1
|
||||
lda w1
|
||||
//SEG12 [6] *((const byte*) main::SCREEN#0) ← (byte~) main::$3 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
//SEG13 [7] (byte~) main::$4 ← > (word) main::w1#0 -- vbuaa=_hi_vwuz1
|
||||
lda w1+1
|
||||
//SEG14 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN+1
|
||||
//SEG15 [9] (word) main::w2#0 ← *((const word*) main::words#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_WORD) -- vwuz1=_deref_pwuc1
|
||||
lda words+2*SIZEOF_WORD
|
||||
sta w2
|
||||
lda words+2*SIZEOF_WORD+1
|
||||
sta w2+1
|
||||
//SEG16 [10] (byte~) main::$6 ← < (word) main::w2#0 -- vbuaa=_lo_vwuz1
|
||||
lda w2
|
||||
//SEG17 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$6 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN+2
|
||||
//SEG18 [12] (byte~) main::$7 ← > (word) main::w2#0 -- vbuaa=_hi_vwuz1
|
||||
lda w2+1
|
||||
//SEG19 [13] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$7 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN+3
|
||||
//SEG20 main::@return
|
||||
//SEG21 [14] return
|
||||
rts
|
||||
}
|
||||
|
24
src/test/ref/word-pointer-math-0.sym
Normal file
24
src/test/ref/word-pointer-math-0.sym
Normal file
@ -0,0 +1,24 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(byte~) main::$3 reg byte a 4.0
|
||||
(byte~) main::$4 reg byte a 4.0
|
||||
(byte~) main::$6 reg byte a 4.0
|
||||
(byte~) main::$7 reg byte a 4.0
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400+(byte/signed byte/word/signed word/dword/signed dword) 6*(byte/signed byte/word/signed word/dword/signed dword) $28
|
||||
(word) main::w1
|
||||
(word) main::w1#0 w1 zp ZP_WORD:2 2.0
|
||||
(word) main::w2
|
||||
(word) main::w2#0 w2 zp ZP_WORD:2 2.0
|
||||
(word*) main::words
|
||||
(const word*) main::words#0 words = ((word*))(word/signed word/dword/signed dword) $400
|
||||
|
||||
zp ZP_WORD:2 [ main::w1#0 main::w2#0 ]
|
||||
reg byte a [ main::$3 ]
|
||||
reg byte a [ main::$4 ]
|
||||
reg byte a [ main::$6 ]
|
||||
reg byte a [ main::$7 ]
|
@ -12,6 +12,7 @@ main: {
|
||||
tax
|
||||
b1:
|
||||
txa
|
||||
asl
|
||||
clc
|
||||
adc #<words
|
||||
sta _0
|
||||
|
@ -13,18 +13,19 @@ main: scope:[main] from @1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::idx#4 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::idx#3 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2
|
||||
[7] (word) main::w#0 ← *((word*~) main::$0)
|
||||
[8] (byte~) main::$1 ← < (word) main::w#0
|
||||
[9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1
|
||||
[10] (byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
[11] (byte~) main::$2 ← > (word) main::w#0
|
||||
[12] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2
|
||||
[13] (byte) main::idx#2 ← ++ (byte) main::idx#1
|
||||
[14] (byte) main::idx#3 ← ++ (byte) main::idx#2
|
||||
[15] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1
|
||||
[6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4
|
||||
[8] (word) main::w#0 ← *((word*~) main::$0)
|
||||
[9] (byte~) main::$1 ← < (word) main::w#0
|
||||
[10] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1
|
||||
[11] (byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
[12] (byte~) main::$2 ← > (word) main::w#0
|
||||
[13] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2
|
||||
[14] (byte) main::idx#2 ← ++ (byte) main::idx#1
|
||||
[15] (byte) main::idx#3 ← ++ (byte) main::idx#2
|
||||
[16] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[17] return
|
||||
[18] return
|
||||
to:@return
|
||||
|
@ -1,3 +1,4 @@
|
||||
Fixing pointer addition (word*~) main::$0 ← (word[]) main::words + (byte) main::i
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -11,7 +12,8 @@ main: scope:[main] from @1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::idx#4 ← phi( main/(byte) main::idx#0 main::@1/(byte) main::idx#3 )
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
(word*~) main::$0 ← (word[]) main::words#0 + (byte) main::i#2
|
||||
(byte) main::$4 ← (byte) main::i#2 * (const byte) SIZEOF_WORD
|
||||
(word*~) main::$0 ← (word[]) main::words#0 + (byte) main::$4
|
||||
(word) main::w#0 ← *((word*~) main::$0)
|
||||
(byte~) main::$1 ← < (word) main::w#0
|
||||
*((byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1
|
||||
@ -39,11 +41,13 @@ SYMBOL TABLE SSA
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(void()) main()
|
||||
(word*~) main::$0
|
||||
(byte~) main::$1
|
||||
(byte~) main::$2
|
||||
(bool~) main::$3
|
||||
(byte) main::$4
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
@ -65,7 +69,7 @@ SYMBOL TABLE SSA
|
||||
|
||||
Culled Empty Block (label) @2
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Simple Condition (bool~) main::$3 [16] if((byte) main::i#1!=rangelast(0,3)) goto main::@1
|
||||
Simple Condition (bool~) main::$3 [17] if((byte) main::i#1!=rangelast(0,3)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const word[]) main::words#0 = { $3130, $3332, $3534, $3736 }
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
|
||||
@ -74,6 +78,9 @@ Constant (const byte) main::i#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value if(main::i#1!=rangelast(0,3)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
Rewriting multiplication to use shift (byte) main::$4 ← (byte) main::i#2 * (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2MultiplyToShiftRewriting
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Inlining constant with var siblings (const byte) main::idx#0
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
@ -88,8 +95,8 @@ CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced [18] main::i#3 ← main::i#1
|
||||
Coalesced [19] main::idx#5 ← main::idx#3
|
||||
Coalesced [19] main::i#3 ← main::i#1
|
||||
Coalesced [20] main::idx#5 ← main::idx#3
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) main::@3
|
||||
Adding NOP phi() at start of @begin
|
||||
@ -113,20 +120,21 @@ main: scope:[main] from @1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::idx#4 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::idx#3 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2
|
||||
[7] (word) main::w#0 ← *((word*~) main::$0)
|
||||
[8] (byte~) main::$1 ← < (word) main::w#0
|
||||
[9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1
|
||||
[10] (byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
[11] (byte~) main::$2 ← > (word) main::w#0
|
||||
[12] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2
|
||||
[13] (byte) main::idx#2 ← ++ (byte) main::idx#1
|
||||
[14] (byte) main::idx#3 ← ++ (byte) main::idx#2
|
||||
[15] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1
|
||||
[6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4
|
||||
[8] (word) main::w#0 ← *((word*~) main::$0)
|
||||
[9] (byte~) main::$1 ← < (word) main::w#0
|
||||
[10] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1
|
||||
[11] (byte) main::idx#1 ← ++ (byte) main::idx#4
|
||||
[12] (byte~) main::$2 ← > (word) main::w#0
|
||||
[13] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2
|
||||
[14] (byte) main::idx#2 ← ++ (byte) main::idx#1
|
||||
[15] (byte) main::idx#3 ← ++ (byte) main::idx#2
|
||||
[16] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[17] return
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
|
||||
@ -135,15 +143,16 @@ VARIABLE REGISTER WEIGHTS
|
||||
(word*~) main::$0 22.0
|
||||
(byte~) main::$1 22.0
|
||||
(byte~) main::$2 22.0
|
||||
(byte) main::$4 22.0
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 3.3000000000000003
|
||||
(byte) main::i#2 3.0
|
||||
(byte) main::idx
|
||||
(byte) main::idx#1 11.0
|
||||
(byte) main::idx#2 22.0
|
||||
(byte) main::idx#3 7.333333333333333
|
||||
(byte) main::idx#4 6.6000000000000005
|
||||
(byte) main::idx#4 5.5
|
||||
(word) main::w
|
||||
(word) main::w#0 8.25
|
||||
(word[]) main::words
|
||||
@ -151,6 +160,7 @@ VARIABLE REGISTER WEIGHTS
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::idx#4 main::idx#3 ]
|
||||
Added variable main::$4 to zero page equivalence class [ main::$4 ]
|
||||
Added variable main::$0 to zero page equivalence class [ main::$0 ]
|
||||
Added variable main::w#0 to zero page equivalence class [ main::w#0 ]
|
||||
Added variable main::$1 to zero page equivalence class [ main::$1 ]
|
||||
@ -160,6 +170,7 @@ Added variable main::idx#2 to zero page equivalence class [ main::idx#2 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::idx#4 main::idx#3 ]
|
||||
[ main::$4 ]
|
||||
[ main::$0 ]
|
||||
[ main::w#0 ]
|
||||
[ main::$1 ]
|
||||
@ -168,12 +179,13 @@ Complete equivalence classes
|
||||
[ main::idx#2 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Allocated zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ]
|
||||
Allocated zp ZP_WORD:4 [ main::$0 ]
|
||||
Allocated zp ZP_WORD:6 [ main::w#0 ]
|
||||
Allocated zp ZP_BYTE:8 [ main::$1 ]
|
||||
Allocated zp ZP_BYTE:9 [ main::idx#1 ]
|
||||
Allocated zp ZP_BYTE:10 [ main::$2 ]
|
||||
Allocated zp ZP_BYTE:11 [ main::idx#2 ]
|
||||
Allocated zp ZP_BYTE:4 [ main::$4 ]
|
||||
Allocated zp ZP_WORD:5 [ main::$0 ]
|
||||
Allocated zp ZP_WORD:7 [ main::w#0 ]
|
||||
Allocated zp ZP_BYTE:9 [ main::$1 ]
|
||||
Allocated zp ZP_BYTE:10 [ main::idx#1 ]
|
||||
Allocated zp ZP_BYTE:11 [ main::$2 ]
|
||||
Allocated zp ZP_BYTE:12 [ main::idx#2 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
@ -202,12 +214,13 @@ bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label _0 = 4
|
||||
.label _1 = 8
|
||||
.label _2 = $a
|
||||
.label w = 6
|
||||
.label idx = 9
|
||||
.label idx_2 = $b
|
||||
.label _0 = 5
|
||||
.label _1 = 9
|
||||
.label _2 = $b
|
||||
.label _4 = 4
|
||||
.label w = 7
|
||||
.label idx = $a
|
||||
.label idx_2 = $c
|
||||
.label idx_3 = 3
|
||||
.label i = 2
|
||||
.label idx_4 = 3
|
||||
@ -227,99 +240,108 @@ main: {
|
||||
jmp b1
|
||||
//SEG17 main::@1
|
||||
b1:
|
||||
//SEG18 [6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2 -- pwuz1=pwuc1_plus_vbuz2
|
||||
//SEG18 [6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_rol_1
|
||||
lda i
|
||||
asl
|
||||
sta _4
|
||||
//SEG19 [7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4 -- pwuz1=pwuc1_plus_vbuz2
|
||||
lda _4
|
||||
clc
|
||||
adc #<words
|
||||
sta _0
|
||||
lda #>words
|
||||
adc #0
|
||||
sta _0+1
|
||||
//SEG19 [7] (word) main::w#0 ← *((word*~) main::$0) -- vwuz1=_deref_pwuz2
|
||||
//SEG20 [8] (word) main::w#0 ← *((word*~) main::$0) -- vwuz1=_deref_pwuz2
|
||||
ldy #0
|
||||
lda (_0),y
|
||||
sta w
|
||||
iny
|
||||
lda (_0),y
|
||||
sta w+1
|
||||
//SEG20 [8] (byte~) main::$1 ← < (word) main::w#0 -- vbuz1=_lo_vwuz2
|
||||
//SEG21 [9] (byte~) main::$1 ← < (word) main::w#0 -- vbuz1=_lo_vwuz2
|
||||
lda w
|
||||
sta _1
|
||||
//SEG21 [9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
//SEG22 [10] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda _1
|
||||
ldy idx_4
|
||||
sta SCREEN,y
|
||||
//SEG22 [10] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuz1=_inc_vbuz2
|
||||
//SEG23 [11] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuz1=_inc_vbuz2
|
||||
ldy idx_4
|
||||
iny
|
||||
sty idx
|
||||
//SEG23 [11] (byte~) main::$2 ← > (word) main::w#0 -- vbuz1=_hi_vwuz2
|
||||
//SEG24 [12] (byte~) main::$2 ← > (word) main::w#0 -- vbuz1=_hi_vwuz2
|
||||
lda w+1
|
||||
sta _2
|
||||
//SEG24 [12] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
//SEG25 [13] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda _2
|
||||
ldy idx
|
||||
sta SCREEN,y
|
||||
//SEG25 [13] (byte) main::idx#2 ← ++ (byte) main::idx#1 -- vbuz1=_inc_vbuz2
|
||||
//SEG26 [14] (byte) main::idx#2 ← ++ (byte) main::idx#1 -- vbuz1=_inc_vbuz2
|
||||
ldy idx
|
||||
iny
|
||||
sty idx_2
|
||||
//SEG26 [14] (byte) main::idx#3 ← ++ (byte) main::idx#2 -- vbuz1=_inc_vbuz2
|
||||
//SEG27 [15] (byte) main::idx#3 ← ++ (byte) main::idx#2 -- vbuz1=_inc_vbuz2
|
||||
ldy idx_2
|
||||
iny
|
||||
sty idx_3
|
||||
//SEG27 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
//SEG28 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc i
|
||||
//SEG28 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
//SEG29 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #4
|
||||
cmp i
|
||||
bne b1_from_b1
|
||||
jmp breturn
|
||||
//SEG29 main::@return
|
||||
//SEG30 main::@return
|
||||
breturn:
|
||||
//SEG30 [17] return
|
||||
//SEG31 [18] return
|
||||
rts
|
||||
// Clever word array that represents C64 numbers 0-7
|
||||
words: .word $3130, $3332, $3534, $3736
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2 [ main::i#2 main::idx#4 main::$0 ] ( main:2 [ main::i#2 main::idx#4 main::$0 ] ) always clobbers reg byte a
|
||||
Statement [6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::idx#4 main::$4 ] ( main:2 [ main::i#2 main::idx#4 main::$4 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ]
|
||||
Statement [7] (word) main::w#0 ← *((word*~) main::$0) [ main::i#2 main::idx#4 main::w#0 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4 [ main::i#2 main::idx#4 main::$0 ] ( main:2 [ main::i#2 main::idx#4 main::$0 ] ) always clobbers reg byte a
|
||||
Statement [8] (word) main::w#0 ← *((word*~) main::$0) [ main::i#2 main::idx#4 main::w#0 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 ] ) always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ]
|
||||
Statement [8] (byte~) main::$1 ← < (word) main::w#0 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [11] (byte~) main::$2 ← > (word) main::w#0 [ main::i#2 main::idx#1 main::$2 ] ( main:2 [ main::i#2 main::idx#1 main::$2 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:9 [ main::idx#1 ]
|
||||
Statement [6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2 [ main::i#2 main::idx#4 main::$0 ] ( main:2 [ main::i#2 main::idx#4 main::$0 ] ) always clobbers reg byte a
|
||||
Statement [7] (word) main::w#0 ← *((word*~) main::$0) [ main::i#2 main::idx#4 main::w#0 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [8] (byte~) main::$1 ← < (word) main::w#0 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [11] (byte~) main::$2 ← > (word) main::w#0 [ main::i#2 main::idx#1 main::$2 ] ( main:2 [ main::i#2 main::idx#1 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte~) main::$1 ← < (word) main::w#0 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [12] (byte~) main::$2 ← > (word) main::w#0 [ main::i#2 main::idx#1 main::$2 ] ( main:2 [ main::i#2 main::idx#1 main::$2 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:10 [ main::idx#1 ]
|
||||
Statement [6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::idx#4 main::$4 ] ( main:2 [ main::i#2 main::idx#4 main::$4 ] ) always clobbers reg byte a
|
||||
Statement [7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4 [ main::i#2 main::idx#4 main::$0 ] ( main:2 [ main::i#2 main::idx#4 main::$0 ] ) always clobbers reg byte a
|
||||
Statement [8] (word) main::w#0 ← *((word*~) main::$0) [ main::i#2 main::idx#4 main::w#0 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [9] (byte~) main::$1 ← < (word) main::w#0 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ( main:2 [ main::i#2 main::idx#4 main::w#0 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [12] (byte~) main::$2 ← > (word) main::w#0 [ main::i#2 main::idx#1 main::$2 ] ( main:2 [ main::i#2 main::idx#1 main::$2 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x ,
|
||||
Potential registers zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ] : zp ZP_BYTE:3 , reg byte x ,
|
||||
Potential registers zp ZP_WORD:4 [ main::$0 ] : zp ZP_WORD:4 ,
|
||||
Potential registers zp ZP_WORD:6 [ main::w#0 ] : zp ZP_WORD:6 ,
|
||||
Potential registers zp ZP_BYTE:8 [ main::$1 ] : zp ZP_BYTE:8 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:9 [ main::idx#1 ] : zp ZP_BYTE:9 , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:10 [ main::$2 ] : zp ZP_BYTE:10 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:11 [ main::idx#2 ] : zp ZP_BYTE:11 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:4 [ main::$4 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_WORD:5 [ main::$0 ] : zp ZP_WORD:5 ,
|
||||
Potential registers zp ZP_WORD:7 [ main::w#0 ] : zp ZP_WORD:7 ,
|
||||
Potential registers zp ZP_BYTE:9 [ main::$1 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:10 [ main::idx#1 ] : zp ZP_BYTE:10 , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:11 [ main::$2 ] : zp ZP_BYTE:11 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:12 [ main::idx#2 ] : zp ZP_BYTE:12 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 22: zp ZP_WORD:4 [ main::$0 ] 22: zp ZP_BYTE:8 [ main::$1 ] 22: zp ZP_BYTE:10 [ main::$2 ] 22: zp ZP_BYTE:11 [ main::idx#2 ] 19.8: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 13.93: zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ] 11: zp ZP_BYTE:9 [ main::idx#1 ] 8.25: zp ZP_WORD:6 [ main::w#0 ]
|
||||
Uplift Scope [main] 22: zp ZP_BYTE:4 [ main::$4 ] 22: zp ZP_WORD:5 [ main::$0 ] 22: zp ZP_BYTE:9 [ main::$1 ] 22: zp ZP_BYTE:11 [ main::$2 ] 22: zp ZP_BYTE:12 [ main::idx#2 ] 19.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 12.83: zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ] 11: zp ZP_BYTE:10 [ main::idx#1 ] 8.25: zp ZP_WORD:7 [ main::w#0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 1053 combination zp ZP_WORD:4 [ main::$0 ] reg byte a [ main::$1 ] reg byte a [ main::$2 ] reg byte a [ main::idx#2 ] reg byte x [ main::i#2 main::i#1 ] zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ] zp ZP_BYTE:9 [ main::idx#1 ] zp ZP_WORD:6 [ main::w#0 ]
|
||||
Limited combination testing to 100 combinations of 768 possible.
|
||||
Uplifting [] best 1053 combination
|
||||
Uplifting [main] best 1173 combination reg byte a [ main::$4 ] zp ZP_WORD:5 [ main::$0 ] reg byte a [ main::$1 ] reg byte a [ main::$2 ] reg byte a [ main::idx#2 ] zp ZP_BYTE:2 [ main::i#2 main::i#1 ] zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ] zp ZP_BYTE:10 [ main::idx#1 ] zp ZP_WORD:7 [ main::w#0 ]
|
||||
Limited combination testing to 100 combinations of 3072 possible.
|
||||
Uplifting [] best 1173 combination
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Uplifting [main] best 1073 combination reg byte x [ main::i#2 main::i#1 ]
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:3 [ main::idx#4 main::idx#3 ]
|
||||
Uplifting [main] best 1053 combination zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ]
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:9 [ main::idx#1 ]
|
||||
Uplifting [main] best 963 combination reg byte y [ main::idx#1 ]
|
||||
Uplifting [main] best 1073 combination zp ZP_BYTE:3 [ main::idx#4 main::idx#3 ]
|
||||
Attempting to uplift remaining variables inzp ZP_BYTE:10 [ main::idx#1 ]
|
||||
Uplifting [main] best 983 combination reg byte y [ main::idx#1 ]
|
||||
Allocated (was zp ZP_BYTE:3) zp ZP_BYTE:2 [ main::idx#4 main::idx#3 ]
|
||||
Allocated (was zp ZP_WORD:4) zp ZP_WORD:3 [ main::$0 ]
|
||||
Allocated (was zp ZP_WORD:6) zp ZP_WORD:5 [ main::w#0 ]
|
||||
Allocated (was zp ZP_WORD:5) zp ZP_WORD:3 [ main::$0 ]
|
||||
Allocated (was zp ZP_WORD:7) zp ZP_WORD:5 [ main::w#0 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
@ -366,49 +388,51 @@ main: {
|
||||
jmp b1
|
||||
//SEG17 main::@1
|
||||
b1:
|
||||
//SEG18 [6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2 -- pwuz1=pwuc1_plus_vbuxx
|
||||
//SEG18 [6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1
|
||||
txa
|
||||
asl
|
||||
//SEG19 [7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4 -- pwuz1=pwuc1_plus_vbuaa
|
||||
clc
|
||||
adc #<words
|
||||
sta _0
|
||||
lda #>words
|
||||
adc #0
|
||||
sta _0+1
|
||||
//SEG19 [7] (word) main::w#0 ← *((word*~) main::$0) -- vwuz1=_deref_pwuz2
|
||||
//SEG20 [8] (word) main::w#0 ← *((word*~) main::$0) -- vwuz1=_deref_pwuz2
|
||||
ldy #0
|
||||
lda (_0),y
|
||||
sta w
|
||||
iny
|
||||
lda (_0),y
|
||||
sta w+1
|
||||
//SEG20 [8] (byte~) main::$1 ← < (word) main::w#0 -- vbuaa=_lo_vwuz1
|
||||
//SEG21 [9] (byte~) main::$1 ← < (word) main::w#0 -- vbuaa=_lo_vwuz1
|
||||
lda w
|
||||
//SEG21 [9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuaa
|
||||
//SEG22 [10] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuaa
|
||||
ldy idx
|
||||
sta SCREEN,y
|
||||
//SEG22 [10] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuyy=_inc_vbuz1
|
||||
//SEG23 [11] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuyy=_inc_vbuz1
|
||||
ldy idx
|
||||
iny
|
||||
//SEG23 [11] (byte~) main::$2 ← > (word) main::w#0 -- vbuaa=_hi_vwuz1
|
||||
//SEG24 [12] (byte~) main::$2 ← > (word) main::w#0 -- vbuaa=_hi_vwuz1
|
||||
lda w+1
|
||||
//SEG24 [12] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2 -- pbuc1_derefidx_vbuyy=vbuaa
|
||||
//SEG25 [13] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2 -- pbuc1_derefidx_vbuyy=vbuaa
|
||||
sta SCREEN,y
|
||||
//SEG25 [13] (byte) main::idx#2 ← ++ (byte) main::idx#1 -- vbuaa=_inc_vbuyy
|
||||
//SEG26 [14] (byte) main::idx#2 ← ++ (byte) main::idx#1 -- vbuaa=_inc_vbuyy
|
||||
iny
|
||||
tya
|
||||
//SEG26 [14] (byte) main::idx#3 ← ++ (byte) main::idx#2 -- vbuz1=_inc_vbuaa
|
||||
//SEG27 [15] (byte) main::idx#3 ← ++ (byte) main::idx#2 -- vbuz1=_inc_vbuaa
|
||||
clc
|
||||
adc #1
|
||||
sta idx
|
||||
//SEG27 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
//SEG28 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG28 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
//SEG29 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #4
|
||||
bne b1_from_b1
|
||||
jmp breturn
|
||||
//SEG29 main::@return
|
||||
//SEG30 main::@return
|
||||
breturn:
|
||||
//SEG30 [17] return
|
||||
//SEG31 [18] return
|
||||
rts
|
||||
// Clever word array that represents C64 numbers 0-7
|
||||
words: .word $3130, $3332, $3534, $3736
|
||||
@ -450,18 +474,19 @@ FINAL SYMBOL TABLE
|
||||
(word*~) main::$0 $0 zp ZP_WORD:3 22.0
|
||||
(byte~) main::$1 reg byte a 22.0
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(byte) main::$4 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 3.3000000000000003
|
||||
(byte) main::i#2 reg byte x 3.0
|
||||
(byte) main::idx
|
||||
(byte) main::idx#1 reg byte y 11.0
|
||||
(byte) main::idx#2 reg byte a 22.0
|
||||
(byte) main::idx#3 idx zp ZP_BYTE:2 7.333333333333333
|
||||
(byte) main::idx#4 idx zp ZP_BYTE:2 6.6000000000000005
|
||||
(byte) main::idx#4 idx zp ZP_BYTE:2 5.5
|
||||
(word) main::w
|
||||
(word) main::w#0 w zp ZP_WORD:5 8.25
|
||||
(word[]) main::words
|
||||
@ -469,6 +494,7 @@ FINAL SYMBOL TABLE
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp ZP_BYTE:2 [ main::idx#4 main::idx#3 ]
|
||||
reg byte a [ main::$4 ]
|
||||
zp ZP_WORD:3 [ main::$0 ]
|
||||
zp ZP_WORD:5 [ main::w#0 ]
|
||||
reg byte a [ main::$1 ]
|
||||
@ -478,7 +504,7 @@ reg byte a [ main::idx#2 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 831
|
||||
Score: 851
|
||||
|
||||
//SEG0 File Comments
|
||||
// Tests simple word pointer math
|
||||
@ -511,46 +537,48 @@ main: {
|
||||
//SEG16 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
//SEG17 main::@1
|
||||
b1:
|
||||
//SEG18 [6] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::i#2 -- pwuz1=pwuc1_plus_vbuxx
|
||||
//SEG18 [6] (byte) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1
|
||||
txa
|
||||
asl
|
||||
//SEG19 [7] (word*~) main::$0 ← (const word[]) main::words#0 + (byte) main::$4 -- pwuz1=pwuc1_plus_vbuaa
|
||||
clc
|
||||
adc #<words
|
||||
sta _0
|
||||
lda #>words
|
||||
adc #0
|
||||
sta _0+1
|
||||
//SEG19 [7] (word) main::w#0 ← *((word*~) main::$0) -- vwuz1=_deref_pwuz2
|
||||
//SEG20 [8] (word) main::w#0 ← *((word*~) main::$0) -- vwuz1=_deref_pwuz2
|
||||
ldy #0
|
||||
lda (_0),y
|
||||
sta w
|
||||
iny
|
||||
lda (_0),y
|
||||
sta w+1
|
||||
//SEG20 [8] (byte~) main::$1 ← < (word) main::w#0 -- vbuaa=_lo_vwuz1
|
||||
//SEG21 [9] (byte~) main::$1 ← < (word) main::w#0 -- vbuaa=_lo_vwuz1
|
||||
lda w
|
||||
//SEG21 [9] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuaa
|
||||
//SEG22 [10] *((const byte*) main::SCREEN#0 + (byte) main::idx#4) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuaa
|
||||
ldy idx
|
||||
sta SCREEN,y
|
||||
//SEG22 [10] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuyy=_inc_vbuz1
|
||||
//SEG23 [11] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuyy=_inc_vbuz1
|
||||
iny
|
||||
//SEG23 [11] (byte~) main::$2 ← > (word) main::w#0 -- vbuaa=_hi_vwuz1
|
||||
//SEG24 [12] (byte~) main::$2 ← > (word) main::w#0 -- vbuaa=_hi_vwuz1
|
||||
lda w+1
|
||||
//SEG24 [12] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2 -- pbuc1_derefidx_vbuyy=vbuaa
|
||||
//SEG25 [13] *((const byte*) main::SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$2 -- pbuc1_derefidx_vbuyy=vbuaa
|
||||
sta SCREEN,y
|
||||
//SEG25 [13] (byte) main::idx#2 ← ++ (byte) main::idx#1 -- vbuaa=_inc_vbuyy
|
||||
//SEG26 [14] (byte) main::idx#2 ← ++ (byte) main::idx#1 -- vbuaa=_inc_vbuyy
|
||||
iny
|
||||
tya
|
||||
//SEG26 [14] (byte) main::idx#3 ← ++ (byte) main::idx#2 -- vbuz1=_inc_vbuaa
|
||||
//SEG27 [15] (byte) main::idx#3 ← ++ (byte) main::idx#2 -- vbuz1=_inc_vbuaa
|
||||
clc
|
||||
adc #1
|
||||
sta idx
|
||||
//SEG27 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
//SEG28 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG28 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
//SEG29 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #4
|
||||
bne b1
|
||||
//SEG29 main::@return
|
||||
//SEG30 [17] return
|
||||
//SEG30 main::@return
|
||||
//SEG31 [18] return
|
||||
rts
|
||||
// Clever word array that represents C64 numbers 0-7
|
||||
words: .word $3130, $3332, $3534, $3736
|
||||
|
@ -5,18 +5,19 @@
|
||||
(word*~) main::$0 $0 zp ZP_WORD:3 22.0
|
||||
(byte~) main::$1 reg byte a 22.0
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(byte) main::$4 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 3.3000000000000003
|
||||
(byte) main::i#2 reg byte x 3.0
|
||||
(byte) main::idx
|
||||
(byte) main::idx#1 reg byte y 11.0
|
||||
(byte) main::idx#2 reg byte a 22.0
|
||||
(byte) main::idx#3 idx zp ZP_BYTE:2 7.333333333333333
|
||||
(byte) main::idx#4 idx zp ZP_BYTE:2 6.6000000000000005
|
||||
(byte) main::idx#4 idx zp ZP_BYTE:2 5.5
|
||||
(word) main::w
|
||||
(word) main::w#0 w zp ZP_WORD:5 8.25
|
||||
(word[]) main::words
|
||||
@ -24,6 +25,7 @@
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp ZP_BYTE:2 [ main::idx#4 main::idx#3 ]
|
||||
reg byte a [ main::$4 ]
|
||||
zp ZP_WORD:3 [ main::$0 ]
|
||||
zp ZP_WORD:5 [ main::w#0 ]
|
||||
reg byte a [ main::$1 ]
|
||||
|
Loading…
Reference in New Issue
Block a user