mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-23 23:32:55 +00:00
Merge remote-tracking branch 'origin/master' into 180-type-system
This commit is contained in:
commit
93937b60d0
@ -222,6 +222,7 @@ public class Compiler {
|
||||
assertions.add(new Pass2AssertNoLabels(program));
|
||||
assertions.add(new Pass2AssertSingleAssignment(program));
|
||||
assertions.add(new Pass2AssertRValues(program));
|
||||
assertions.add(new Pass2AssertPhiPredecessors(program));
|
||||
for(Pass2SsaAssertion assertion : assertions) {
|
||||
assertion.check();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementLabel;
|
||||
import dk.camelot64.kickc.model.statements.StatementProcedureBegin;
|
||||
import dk.camelot64.kickc.model.statements.StatementProcedureEnd;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -11,7 +12,7 @@ import java.util.List;
|
||||
/** A sequence of Statements */
|
||||
public class StatementSequence {
|
||||
|
||||
private List<Statement> statements;
|
||||
private ArrayList<Statement> statements;
|
||||
|
||||
public StatementSequence() {
|
||||
this.statements = new ArrayList<>();
|
||||
@ -43,4 +44,17 @@ public class StatementSequence {
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Look backwar from the end of the sequence and find the last label
|
||||
* @return The label of the block, currently being build
|
||||
*/
|
||||
public LabelRef getCurrentBlockLabel() {
|
||||
for(int i = statements.size()-1; i >= 0; i--) {
|
||||
Statement statement = statements.get(i);
|
||||
if(statement instanceof StatementLabel) {
|
||||
return ((StatementLabel) statement).getLabel();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInteger;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
|
||||
import dk.camelot64.kickc.model.values.ConstantChar;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||
@ -24,6 +25,8 @@ public class OperatorMinus extends OperatorBinary {
|
||||
} else if(left instanceof ConstantPointer && right instanceof ConstantInteger) {
|
||||
long location = ((ConstantPointer) left).getLocation() - ((ConstantInteger) right).getInteger();
|
||||
return new ConstantPointer(location, ((ConstantPointer) left).getElementType());
|
||||
} else if(left instanceof ConstantChar && right instanceof ConstantInteger) {
|
||||
return new ConstantInteger(((ConstantChar) left).getChar() - ((ConstantInteger) right).getInteger());
|
||||
}
|
||||
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
||||
}
|
||||
|
@ -1371,18 +1371,20 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
RValue falseValue = (RValue) this.visit(ctx.expr(2));
|
||||
VariableRef falseVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment(falseVar, null, null, falseValue, new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
LabelRef falseExitLabel = sequence.getCurrentBlockLabel();
|
||||
sequence.addStatement(new StatementJump(endJumpLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
sequence.addStatement(new StatementLabel(trueLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
RValue trueValue = (RValue) this.visit(ctx.expr(1));
|
||||
VariableRef trueVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment(trueVar, null, null, trueValue, new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
LabelRef trueExitLabel = sequence.getCurrentBlockLabel();
|
||||
sequence.addStatement(new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
StatementPhiBlock phiBlock = new StatementPhiBlock(Comment.NO_COMMENTS);
|
||||
phiBlock.setSource(new StatementSource(ctx));
|
||||
VariableRef finalVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
StatementPhiBlock.PhiVariable phiVariable = phiBlock.addPhiVariable(finalVar);
|
||||
phiVariable.setrValue(trueLabel.getRef(), trueVar);
|
||||
phiVariable.setrValue(falseLabel.getRef(), falseVar);
|
||||
phiVariable.setrValue(trueExitLabel, trueVar);
|
||||
phiVariable.setrValue(falseExitLabel, falseVar);
|
||||
sequence.addStatement(phiBlock);
|
||||
return finalVar;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
VariableRef phiLValVarRef = phiVariable.getVariable();
|
||||
VariableVersion versioned = (VariableVersion) getScope().getVariable(phiLValVarRef);
|
||||
VariableUnversioned unversioned = versioned.getVersionOf();
|
||||
List<ControlFlowBlock> predecessors = getPredecessors(block);
|
||||
List<ControlFlowBlock> predecessors = getPhiPredecessors(block, getProgram());
|
||||
for(ControlFlowBlock predecessor : predecessors) {
|
||||
LabelRef predecessorLabel = predecessor.getLabel();
|
||||
Map<VariableUnversioned, VariableVersion> predecessorMap = symbolMap.get(predecessorLabel);
|
||||
@ -245,15 +245,15 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
* @param block The block to examine
|
||||
* @return All predecessor blocks
|
||||
*/
|
||||
private List<ControlFlowBlock> getPredecessors(ControlFlowBlock block) {
|
||||
List<ControlFlowBlock> predecessors = getGraph().getPredecessors(block);
|
||||
Symbol symbol = getScope().getSymbol(block.getLabel());
|
||||
public static List<ControlFlowBlock> getPhiPredecessors(ControlFlowBlock block, Program program) {
|
||||
List<ControlFlowBlock> predecessors = program.getGraph().getPredecessors(block);
|
||||
Symbol symbol = program.getScope().getSymbol(block.getLabel());
|
||||
if(symbol instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) symbol;
|
||||
if(procedure.getInterruptType()!=null || Pass2ConstantIdentification.isAddressOfUsed(procedure.getRef(), getProgram())) {
|
||||
if(procedure.getInterruptType()!=null || Pass2ConstantIdentification.isAddressOfUsed(procedure.getRef(), program)) {
|
||||
// Find all root-level predecessors to the main block
|
||||
ControlFlowBlock mainBlock = getGraph().getBlock(new LabelRef(SymbolRef.MAIN_PROC_NAME));
|
||||
List<ControlFlowBlock> mainPredecessors = getGraph().getPredecessors(mainBlock);
|
||||
ControlFlowBlock mainBlock = program.getGraph().getBlock(new LabelRef(SymbolRef.MAIN_PROC_NAME));
|
||||
List<ControlFlowBlock> mainPredecessors = program.getGraph().getPredecessors(mainBlock);
|
||||
for(ControlFlowBlock mainPredecessor : mainPredecessors) {
|
||||
if(mainPredecessor.getScope().equals(ScopeRef.ROOT)) {
|
||||
predecessors.add(mainPredecessor);
|
||||
|
@ -0,0 +1,39 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** Asserts that the program does not contain any predecessors in Phi-blocks that are not true predecessors */
|
||||
public class Pass2AssertPhiPredecessors extends Pass2SsaAssertion {
|
||||
|
||||
public Pass2AssertPhiPredecessors(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check() throws AssertionFailed {
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
if(block.hasPhiBlock()) {
|
||||
StatementPhiBlock phiBlock = block.getPhiBlock();
|
||||
List<ControlFlowBlock> phiPredecessors = Pass1GenerateSingleStaticAssignmentForm.getPhiPredecessors(block, getProgram());
|
||||
List<LabelRef> predecessors =
|
||||
phiPredecessors.stream().map(ControlFlowBlock::getLabel).collect(Collectors.toList());
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(!predecessors.contains(phiRValue.getPredecessor())) {
|
||||
throw new CompileError("INTERNAL ERROR! Block "+block.getLabel()+" phi references non-predecessor block "+phiRValue.getPredecessor()+
|
||||
"\n "+phiBlock.toString(getProgram(), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -32,6 +32,27 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleLoop() throws IOException, URISyntaxException {
|
||||
compileAndCompare("simple-loop");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLiteralCharMinusNumber() throws IOException, URISyntaxException {
|
||||
compileAndCompare("literal-char-minus-number");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaulNelsenSandboxTernaryError() throws IOException, URISyntaxException {
|
||||
compileAndCompare("sandbox-ternary-error", log().verboseParse().verboseCreateSsa().setVerboseSSAOptimize().verboseStatementSequence());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaulNelsenSandbox() throws IOException, URISyntaxException {
|
||||
compileAndCompare("sandbox");
|
||||
}
|
||||
|
||||
|
||||
//@Test
|
||||
//public void testPointerCast3() throws IOException, URISyntaxException {
|
||||
// compileAndCompare("pointer-cast-3");
|
||||
|
6
src/test/kc/literal-char-minus-number.kc
Normal file
6
src/test/kc/literal-char-minus-number.kc
Normal file
@ -0,0 +1,6 @@
|
||||
// Tests subtracting a number from a literal char
|
||||
|
||||
void main() {
|
||||
const byte* SCREEN = 0x0400;
|
||||
*SCREEN = 'a' - 1;
|
||||
}
|
13
src/test/kc/sandbox-ternary-error.kc
Normal file
13
src/test/kc/sandbox-ternary-error.kc
Normal file
@ -0,0 +1,13 @@
|
||||
// Demonstrates error with nested ternary operator
|
||||
|
||||
void main(void) {
|
||||
const byte* SCREEN = 0x0400;
|
||||
for ( byte b: 0..2 ) {
|
||||
*SCREEN = (b == 0) ? 'a' : ((b == 1) ? 'b' : 'c');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
126
src/test/kc/sandbox.kc
Normal file
126
src/test/kc/sandbox.kc
Normal file
@ -0,0 +1,126 @@
|
||||
import "division"
|
||||
|
||||
const byte * zp1 = 0x61; // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169
|
||||
const byte * zp2 = 0x62;
|
||||
const byte * TIMEHI = 0xA1;
|
||||
const byte * TIMELO = 0xA2;
|
||||
const byte * VICBANK = 0xD018;
|
||||
byte[16] buf16; // "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162
|
||||
byte[100] strTemp;
|
||||
|
||||
// simple 'utoa' without using multiply or divide
|
||||
word append(byte *dst, word value, word sub){
|
||||
*dst = '0';
|
||||
while (value >= sub){ ++*dst; value -= sub; }
|
||||
return value;
|
||||
}
|
||||
void utoa(word value, byte *dst){
|
||||
byte bStarted = 0;
|
||||
if (bStarted == 1 || value >= 10000){ value = append(dst++, value, 10000); bStarted = 1; }
|
||||
if (bStarted == 1 || value >= 1000){ value = append(dst++, value, 1000); bStarted = 1; }
|
||||
if (bStarted == 1 || value >= 100){ value = append(dst++, value, 100); bStarted = 1; }
|
||||
if (bStarted == 1 || value >= 10){ value = append(dst++, value, 10); bStarted = 1; }
|
||||
*dst++ = '0' + (byte)value;
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
byte myprintf(byte *dst, byte *str, word w1, word w2, word w3) {
|
||||
byte bArg = 0, bFormat = 0, bLen = 0;
|
||||
byte bLeadZero, bDigits, bTrailing; // formats
|
||||
byte b, digit;
|
||||
byte[6] buf6;
|
||||
word w;
|
||||
|
||||
for (; *str != 0; ++str) {
|
||||
b = *str;
|
||||
if (bFormat != 0) { // "(bFormat)" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/135
|
||||
if (b == '0') { bLeadZero = 1; continue; }
|
||||
if (b >= '1' && b <= '9') { bDigits = b - '0'; continue; }
|
||||
if (b == '-') { bTrailing = 1; continue; }
|
||||
if (b == 'c'){ // "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170
|
||||
dst[bLen++] = (byte)w;
|
||||
} else if (b == 'd') {
|
||||
utoa(w, buf6);
|
||||
b = 1; while(buf6[b] != 0) ++b; // strlen() not supported -- https://gitlab.com/camelot/kickc/issues/182
|
||||
// if (bDigits > b) is used because non-executing for loop is not supported -- https://gitlab.com/camelot/kickc/issues/183
|
||||
if (bTrailing == 0 && bDigits > b) for (; bDigits > b; --bDigits) dst[bLen++] = (bLeadZero == 0) ? ' ' : '0';
|
||||
for (digit = 0; digit < b; ++digit) dst[bLen++] = buf6[digit];
|
||||
if (bTrailing != 0 && bDigits > b) for (; bDigits > b; --bDigits) dst[bLen++] = ' ';
|
||||
} else if (b == 'x' || b == 'X'){ // hex
|
||||
b = (w >> 4) & 0xF;
|
||||
dst[bLen++] = (b < 10 ? '0' : 0x57) + b; // "('a' - 10)" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/184 [FIXED]
|
||||
b = w & 0xF; dst[bLen++] = (b < 10 ? '0' : 0x57) + b;
|
||||
}
|
||||
bFormat = 0;
|
||||
continue;
|
||||
}
|
||||
if (b == '%') {
|
||||
bFormat = 1;
|
||||
bLeadZero = 0; bDigits = 1; bTrailing = 0; // default format
|
||||
//w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 [FIXED]
|
||||
if (bArg == 0) w = w1;
|
||||
else if (bArg == 1) w = w2;
|
||||
else w = w3;
|
||||
++bArg;
|
||||
continue;
|
||||
}
|
||||
if (b >= 0x41 && b <= 0x5A) b += 0x20; // swap 0x41 / 0x61 when in lower case mode
|
||||
dst[bLen++] = b;
|
||||
}
|
||||
dst[bLen] = 0;
|
||||
return bLen;
|
||||
}
|
||||
|
||||
void Print(){ // can this assembly be placed in a separate file and call it from the C code here?
|
||||
asm {
|
||||
ldy #0
|
||||
loop:
|
||||
lda strTemp,y
|
||||
beq done
|
||||
jsr $FFD2
|
||||
iny
|
||||
jmp loop
|
||||
done:
|
||||
}
|
||||
}
|
||||
|
||||
word div10(word val){
|
||||
val = (val >> 1) + 1;
|
||||
val += val << 1;
|
||||
val += val >> 4;
|
||||
val += val >> 4 >> 4; // >> 8 is not supported?
|
||||
return val >> 4;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
word u;
|
||||
word v;
|
||||
*VICBANK = 23; // lower case mode
|
||||
|
||||
// test performance of 'div16u(10)'
|
||||
u = 28293;
|
||||
for (*zp1 = 0; *zp1 < 10; ++*zp1){
|
||||
*TIMEHI = 0;
|
||||
*TIMELO = 0;
|
||||
for (*zp2 = 0; *zp2 < 200; ++*zp2) v = div16u(u, 10);
|
||||
// lower case letters in string literal are placed in string as 0x01-0x1A, should be 0x61-0x7A
|
||||
// -- as a side-effect of above issue, we can use "m" for carriage return. The normal way is the escape code "\r" but that is not supported --
|
||||
myprintf(strTemp, "200 DIV16U: %5d,%4d IN %04d FRAMESm", u, v, ((word)*TIMEHI << 8) + (word)*TIMELO);
|
||||
Print();
|
||||
u -= 1234;
|
||||
}
|
||||
|
||||
// test performance of 'div10'
|
||||
u = 28293;
|
||||
for (*zp1 = 0; *zp1 < 10; ++*zp1){
|
||||
*TIMEHI = 0;
|
||||
*TIMELO = 0;
|
||||
for (*zp2 = 0; *zp2 < 200; ++*zp2) v = div10(u);
|
||||
myprintf(strTemp, "200 DIV10 : %5d,%4d IN %04d FRAMESm", u, v, ((word)*TIMEHI << 8) + (word)*TIMELO);
|
||||
Print();
|
||||
u -= 1234;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
8
src/test/kc/simple-loop.kc
Normal file
8
src/test/kc/simple-loop.kc
Normal file
@ -0,0 +1,8 @@
|
||||
void main() {
|
||||
const unsigned char* SCREEN = 0x0400;
|
||||
for( unsigned char i = 0; i<128; i+=2) {
|
||||
SCREEN[i] = 'a';
|
||||
(*(unsigned char*)0xD020)=0;
|
||||
}
|
||||
}
|
||||
|
10
src/test/ref/literal-char-minus-number.asm
Normal file
10
src/test/ref/literal-char-minus-number.asm
Normal file
@ -0,0 +1,10 @@
|
||||
// Tests subtracting a number from a literal char
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
lda #'a'-1
|
||||
sta SCREEN
|
||||
rts
|
||||
}
|
15
src/test/ref/literal-char-minus-number.cfg
Normal file
15
src/test/ref/literal-char-minus-number.cfg
Normal file
@ -0,0 +1,15 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] *((const byte*) main::SCREEN#0) ← (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return
|
||||
to:@return
|
210
src/test/ref/literal-char-minus-number.log
Normal file
210
src/test/ref/literal-char-minus-number.log
Normal file
@ -0,0 +1,210 @@
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte/signed byte/word/signed word/dword/signed dword~) main::$0 ← (byte) 'a' - (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
*((byte*) main::SCREEN#0) ← (byte/signed byte/word/signed word/dword/signed dword~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(byte/signed byte/word/signed word/dword/signed dword~) main::$0
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte*) main::SCREEN#0
|
||||
|
||||
Culled Empty Block (label) @2
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
|
||||
Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$0 = 'a'-1
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant inlined main::$0 = (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
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] *((const byte*) main::SCREEN#0) ← (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte*) main::SCREEN
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Tests subtracting a number from a literal char
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2
|
||||
lda #'a'-1
|
||||
sta SCREEN
|
||||
jmp breturn
|
||||
//SEG11 main::@return
|
||||
breturn:
|
||||
//SEG12 [5] return
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] *((const byte*) main::SCREEN#0) ← (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 27 combination
|
||||
Uplifting [] best 27 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Tests subtracting a number from a literal char
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2
|
||||
lda #'a'-1
|
||||
sta SCREEN
|
||||
jmp breturn
|
||||
//SEG11 main::@return
|
||||
breturn:
|
||||
//SEG12 [5] 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
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 12
|
||||
|
||||
//SEG0 File Comments
|
||||
// Tests subtracting a number from a literal char
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG8 @end
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG10 [4] *((const byte*) main::SCREEN#0) ← (byte) 'a'-(byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2
|
||||
lda #'a'-1
|
||||
sta SCREEN
|
||||
//SEG11 main::@return
|
||||
//SEG12 [5] return
|
||||
rts
|
||||
}
|
||||
|
8
src/test/ref/literal-char-minus-number.sym
Normal file
8
src/test/ref/literal-char-minus-number.sym
Normal file
@ -0,0 +1,8 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
|
26
src/test/ref/sandbox-ternary-error.asm
Normal file
26
src/test/ref/sandbox-ternary-error.asm
Normal file
@ -0,0 +1,26 @@
|
||||
// Demonstrates error with nested ternary operator
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
ldx #0
|
||||
b1:
|
||||
cpx #0
|
||||
beq b4
|
||||
cpx #1
|
||||
beq b2
|
||||
lda #'c'
|
||||
jmp b3
|
||||
b2:
|
||||
lda #'b'
|
||||
jmp b3
|
||||
b4:
|
||||
lda #'a'
|
||||
b3:
|
||||
sta SCREEN
|
||||
inx
|
||||
cpx #3
|
||||
bne b1
|
||||
rts
|
||||
}
|
34
src/test/ref/sandbox-ternary-error.cfg
Normal file
34
src/test/ref/sandbox-ternary-error.cfg
Normal file
@ -0,0 +1,34 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (byte) main::b#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@3/(byte) main::b#1 )
|
||||
[6] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@3
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[7] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2
|
||||
[8] phi()
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2 main::@4
|
||||
[9] (byte~) main::$5 ← phi( main::@2/(byte) 'b' main::@4/(byte) 'c' )
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1 main::@5
|
||||
[10] (byte~) main::$7 ← phi( main::@1/(byte) 'a' main::@5/(byte~) main::$5 )
|
||||
[11] *((const byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[12] (byte) main::b#1 ← ++ (byte) main::b#2
|
||||
[13] if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[14] return
|
||||
to:@return
|
988
src/test/ref/sandbox-ternary-error.log
Normal file
988
src/test/ref/sandbox-ternary-error.log
Normal file
@ -0,0 +1,988 @@
|
||||
PARSING src/test/kc/sandbox-ternary-error.kc
|
||||
// Demonstrates error with nested ternary operator
|
||||
|
||||
void main(void) {
|
||||
const byte* SCREEN = 0x0400;
|
||||
for ( byte b: 0..2 ) {
|
||||
*SCREEN = (b == 0) ? 'a' : ((b == 1) ? 'b' : 'c');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
STATEMENTS
|
||||
proc (void()) main()
|
||||
(byte*) main::SCREEN ← (word/signed word/dword/signed dword) $400
|
||||
(byte) main:::1::b ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
main:::1::@1:
|
||||
(var) main:::1::$0 ← (byte) main:::1::b == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
if((var) main:::1::$0) goto main:::1::@2
|
||||
main:::1::@3:
|
||||
(var) main:::1::$1 ← (byte) main:::1::b == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
if((var) main:::1::$1) goto main:::1::@5
|
||||
main:::1::@6:
|
||||
(var) main:::1::$2 ← (byte) 'c'
|
||||
goto main:::1::@7
|
||||
main:::1::@5:
|
||||
(var) main:::1::$3 ← (byte) 'b'
|
||||
main:::1::@7:
|
||||
(var) main:::1::$4 ← phi( main:::1::@5/(var) main:::1::$3 main:::1::@6/(var) main:::1::$2 )
|
||||
(var) main:::1::$5 ← (var) main:::1::$4
|
||||
goto main:::1::@4
|
||||
main:::1::@2:
|
||||
(var) main:::1::$6 ← (byte) 'a'
|
||||
main:::1::@4:
|
||||
(var) main:::1::$7 ← phi( main:::1::@2/(var) main:::1::$6 main:::1::@7/(var) main:::1::$5 )
|
||||
*((byte*) main::SCREEN) ← (var) main:::1::$7
|
||||
(byte) main:::1::b ← (byte) main:::1::b + rangenext(0,2)
|
||||
(var) main:::1::$8 ← (byte) main:::1::b != rangelast(0,2)
|
||||
if((var) main:::1::$8) goto main:::1::@1
|
||||
main::@return:
|
||||
return
|
||||
endproc // main()
|
||||
call main
|
||||
|
||||
SYMBOLS
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(bool~) main::$1
|
||||
(byte~) main::$2
|
||||
(byte~) main::$3
|
||||
(byte~) main::$4
|
||||
(byte~) main::$5
|
||||
(byte~) main::$6
|
||||
(byte~) main::$7
|
||||
(bool~) main::$8
|
||||
(label) main::@1
|
||||
(label) main::@10
|
||||
(label) main::@11
|
||||
(label) main::@12
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@9
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::b
|
||||
|
||||
Promoting word/signed word/dword/signed dword to byte* in main::SCREEN ← ((byte*)) $400
|
||||
INITIAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from
|
||||
[0] (byte*) main::SCREEN ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
[1] (byte) main::b ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[2] (bool~) main::$0 ← (byte) main::b == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[3] if((bool~) main::$0) goto main::@2
|
||||
to:main::@8
|
||||
main::@2: scope:[main] from main::@1 main::@11
|
||||
[4] (byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@8: scope:[main] from main::@1
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@8
|
||||
[5] (bool~) main::$1 ← (byte) main::b == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[6] if((bool~) main::$1) goto main::@5
|
||||
to:main::@9
|
||||
main::@5: scope:[main] from main::@10 main::@3
|
||||
[7] (byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@9: scope:[main] from main::@3
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@9
|
||||
[8] (byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
[9] (byte~) main::$4 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
[10] (byte~) main::$5 ← (byte~) main::$4
|
||||
to:main::@4
|
||||
main::@10: scope:[main] from
|
||||
to:main::@5
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
[11] (byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
[12] *((byte*) main::SCREEN) ← (byte~) main::$7
|
||||
[13] (byte) main::b ← (byte) main::b + rangenext(0,2)
|
||||
[14] (bool~) main::$8 ← (byte) main::b != rangelast(0,2)
|
||||
[15] if((bool~) main::$8) goto main::@1
|
||||
to:main::@12
|
||||
main::@11: scope:[main] from
|
||||
to:main::@2
|
||||
main::@12: scope:[main] from main::@4
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@12
|
||||
[16] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[17] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Removing empty block main::@8
|
||||
Removing empty block main::@9
|
||||
Removing empty block main::@10
|
||||
Removing empty block main::@11
|
||||
Removing empty block main::@12
|
||||
PROCEDURE MODIFY VARIABLE ANALYSIS
|
||||
|
||||
Completing Phi functions...
|
||||
Completing Phi functions...
|
||||
Completing Phi functions...
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
(byte) main::b#2 ← phi( main/(byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
(bool~) main::$0 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
if((bool~) main::$0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte) main::b#5 ← phi( main::@1/(byte) main::b#2 )
|
||||
(byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
(byte) main::b#3 ← phi( main::@1/(byte) main::b#2 )
|
||||
(bool~) main::$1 ← (byte) main::b#3 == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
if((bool~) main::$1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
(byte) main::b#7 ← phi( main::@3/(byte) main::b#3 )
|
||||
(byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
(byte) main::b#8 ← phi( main::@3/(byte) main::b#3 )
|
||||
(byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
(byte) main::b#6 ← phi( main::@5/(byte) main::b#7 main::@6/(byte) main::b#8 )
|
||||
(byte~) main::$4 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
(byte~) main::$5 ← (byte~) main::$4
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
(byte) main::b#4 ← phi( main::@2/(byte) main::b#5 main::@7/(byte) main::b#6 )
|
||||
(byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
*((byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
(byte) main::b#1 ← (byte) main::b#4 + rangenext(0,2)
|
||||
(bool~) main::$8 ← (byte) main::b#1 != rangelast(0,2)
|
||||
if((bool~) main::$8) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
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
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(bool~) main::$1
|
||||
(byte~) main::$2
|
||||
(byte~) main::$3
|
||||
(byte~) main::$4
|
||||
(byte~) main::$5
|
||||
(byte~) main::$6
|
||||
(byte~) main::$7
|
||||
(bool~) main::$8
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte*) main::SCREEN#0
|
||||
(byte) main::b
|
||||
(byte) main::b#0
|
||||
(byte) main::b#1
|
||||
(byte) main::b#2
|
||||
(byte) main::b#3
|
||||
(byte) main::b#4
|
||||
(byte) main::b#5
|
||||
(byte) main::b#6
|
||||
(byte) main::b#7
|
||||
(byte) main::b#8
|
||||
|
||||
Culled Empty Block (label) @2
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
(byte) main::b#2 ← phi( main/(byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
(bool~) main::$0 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
if((bool~) main::$0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte) main::b#5 ← phi( main::@1/(byte) main::b#2 )
|
||||
(byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
(byte) main::b#3 ← phi( main::@1/(byte) main::b#2 )
|
||||
(bool~) main::$1 ← (byte) main::b#3 == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
if((bool~) main::$1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
(byte) main::b#7 ← phi( main::@3/(byte) main::b#3 )
|
||||
(byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
(byte) main::b#8 ← phi( main::@3/(byte) main::b#3 )
|
||||
(byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
(byte) main::b#6 ← phi( main::@5/(byte) main::b#7 main::@6/(byte) main::b#8 )
|
||||
(byte~) main::$4 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
(byte~) main::$5 ← (byte~) main::$4
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
(byte) main::b#4 ← phi( main::@2/(byte) main::b#5 main::@7/(byte) main::b#6 )
|
||||
(byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
*((byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
(byte) main::b#1 ← (byte) main::b#4 + rangenext(0,2)
|
||||
(bool~) main::$8 ← (byte) main::b#1 != rangelast(0,2)
|
||||
if((bool~) main::$8) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Alias (byte) main::b#2 = (byte) main::b#5 (byte) main::b#3 (byte) main::b#7 (byte) main::b#8
|
||||
Alias (byte~) main::$5 = (byte~) main::$4
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
[0] (byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
[1] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[2] (byte) main::b#2 ← phi( main/(byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
[3] (bool~) main::$0 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[4] if((bool~) main::$0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] (byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
[8] (bool~) main::$1 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[9] if((bool~) main::$1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
[11] (byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
[13] (byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
[14] (byte) main::b#6 ← phi( main::@5/(byte) main::b#2 main::@6/(byte) main::b#2 )
|
||||
[14] (byte~) main::$5 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
[16] (byte) main::b#4 ← phi( main::@2/(byte) main::b#2 main::@7/(byte) main::b#6 )
|
||||
[16] (byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
[17] *((byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[18] (byte) main::b#1 ← (byte) main::b#4 + rangenext(0,2)
|
||||
[19] (bool~) main::$8 ← (byte) main::b#1 != rangelast(0,2)
|
||||
[20] if((bool~) main::$8) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[21] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[22] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Alias (byte) main::b#2 = (byte) main::b#6
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
[0] (byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
[1] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[2] (byte) main::b#2 ← phi( main/(byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
[3] (bool~) main::$0 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[4] if((bool~) main::$0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] (byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
[8] (bool~) main::$1 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[9] if((bool~) main::$1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
[11] (byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
[13] (byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
[14] (byte~) main::$5 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
[16] (byte) main::b#4 ← phi( main::@2/(byte) main::b#2 main::@7/(byte) main::b#2 )
|
||||
[16] (byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
[17] *((byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[18] (byte) main::b#1 ← (byte) main::b#4 + rangenext(0,2)
|
||||
[19] (bool~) main::$8 ← (byte) main::b#1 != rangelast(0,2)
|
||||
[20] if((bool~) main::$8) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[21] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[22] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Alias (byte) main::b#2 = (byte) main::b#4
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
[0] (byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
[1] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[2] (byte) main::b#2 ← phi( main/(byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
[3] (bool~) main::$0 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[4] if((bool~) main::$0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] (byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
[8] (bool~) main::$1 ← (byte) main::b#2 == (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[9] if((bool~) main::$1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
[11] (byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
[13] (byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
[14] (byte~) main::$5 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
[16] (byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
[17] *((byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[18] (byte) main::b#1 ← (byte) main::b#2 + rangenext(0,2)
|
||||
[19] (bool~) main::$8 ← (byte) main::b#1 != rangelast(0,2)
|
||||
[20] if((bool~) main::$8) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[21] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[22] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Simple Condition (bool~) main::$0 [4] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2
|
||||
Simple Condition (bool~) main::$1 [9] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5
|
||||
Simple Condition (bool~) main::$8 [20] if((byte) main::b#1!=rangelast(0,2)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
[0] (byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
[1] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[2] (byte) main::b#2 ← phi( main/(byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
[4] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] (byte~) main::$6 ← (byte) 'a'
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
[9] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
[11] (byte~) main::$3 ← (byte) 'b'
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
[13] (byte~) main::$2 ← (byte) 'c'
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
[14] (byte~) main::$5 ← phi( main::@5/(byte~) main::$3 main::@6/(byte~) main::$2 )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
[16] (byte~) main::$7 ← phi( main::@2/(byte~) main::$6 main::@7/(byte~) main::$5 )
|
||||
[17] *((byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[18] (byte) main::b#1 ← (byte) main::b#2 + rangenext(0,2)
|
||||
[20] if((byte) main::b#1!=rangelast(0,2)) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[21] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[22] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
|
||||
Constant (const byte) main::b#0 = 0
|
||||
Constant (const byte) main::$6 = 'a'
|
||||
Constant (const byte) main::$3 = 'b'
|
||||
Constant (const byte) main::$2 = 'c'
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[2] (byte) main::b#2 ← phi( main/(const byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
[4] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
to:main::@4
|
||||
main::@3: scope:[main] from main::@1
|
||||
[9] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5
|
||||
to:main::@6
|
||||
main::@5: scope:[main] from main::@3
|
||||
to:main::@7
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5 main::@6
|
||||
[14] (byte~) main::$5 ← phi( main::@5/(const byte) main::$3 main::@6/(const byte) main::$2 )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@7
|
||||
[16] (byte~) main::$7 ← phi( main::@2/(const byte) main::$6 main::@7/(byte~) main::$5 )
|
||||
[17] *((const byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[18] (byte) main::b#1 ← (byte) main::b#2 + rangenext(0,2)
|
||||
[20] if((byte) main::b#1!=rangelast(0,2)) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[21] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[22] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Resolved ranged next value main::b#1 ← ++ main::b#2 to ++
|
||||
Resolved ranged comparison value if(main::b#1!=rangelast(0,2)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Culled Empty Block (label) main::@2
|
||||
Culled Empty Block (label) main::@5
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
(byte) main::b#2 ← phi( main/(const byte) main::b#0 main::@4/(byte) main::b#1 )
|
||||
if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@4
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1
|
||||
if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@3 main::@6
|
||||
(byte~) main::$5 ← phi( main::@3/(const byte) main::$3 main::@6/(const byte) main::$2 )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@1 main::@7
|
||||
(byte~) main::$7 ← phi( main::@1/(const byte) main::$6 main::@7/(byte~) main::$5 )
|
||||
*((const byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
(byte) main::b#1 ← ++ (byte) main::b#2
|
||||
if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Inlining constant with var siblings (const byte) main::b#0
|
||||
Constant inlined main::$6 = (byte) 'a'
|
||||
Constant inlined main::$3 = (byte) 'b'
|
||||
Constant inlined main::b#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
Constant inlined main::$2 = (byte) 'c'
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[0] (byte) main::b#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@4/(byte) main::b#1 )
|
||||
[1] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@4
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1
|
||||
[2] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@3 main::@6
|
||||
[3] (byte~) main::$5 ← phi( main::@3/(byte) 'b' main::@6/(byte) 'c' )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@1 main::@7
|
||||
[4] (byte~) main::$7 ← phi( main::@1/(byte) 'a' main::@7/(byte~) main::$5 )
|
||||
[5] *((const byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[6] (byte) main::b#1 ← ++ (byte) main::b#2
|
||||
[7] if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[8] return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
[9] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Added new block during phi lifting main::@13(between main::@4 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of main::@6
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 3 initial phi equivalence classes
|
||||
Coalesced [10] main::$9 ← main::$5
|
||||
Coalesced [16] main::b#9 ← main::b#1
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) main::@13
|
||||
Renumbering block main::@3 to main::@2
|
||||
Renumbering block main::@4 to main::@3
|
||||
Renumbering block main::@6 to main::@4
|
||||
Renumbering block main::@7 to main::@5
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of main::@4
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (byte) main::b#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@3/(byte) main::b#1 )
|
||||
[6] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@3
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[7] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2
|
||||
[8] phi()
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2 main::@4
|
||||
[9] (byte~) main::$5 ← phi( main::@2/(byte) 'b' main::@4/(byte) 'c' )
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1 main::@5
|
||||
[10] (byte~) main::$7 ← phi( main::@1/(byte) 'a' main::@5/(byte~) main::$5 )
|
||||
[11] *((const byte*) main::SCREEN#0) ← (byte~) main::$7
|
||||
[12] (byte) main::b#1 ← ++ (byte) main::b#2
|
||||
[13] if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte~) main::$5 11.0
|
||||
(byte~) main::$7 22.0
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::b
|
||||
(byte) main::b#1 16.5
|
||||
(byte) main::b#2 6.285714285714286
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::b#2 main::b#1 ]
|
||||
[ main::$7 main::$5 ]
|
||||
Complete equivalence classes
|
||||
[ main::b#2 main::b#1 ]
|
||||
[ main::$7 main::$5 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::b#2 main::b#1 ]
|
||||
Allocated zp ZP_BYTE:3 [ main::$7 main::$5 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Demonstrates error with nested ternary operator
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label _5 = 3
|
||||
.label _7 = 3
|
||||
.label b = 2
|
||||
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG12 [5] phi (byte) main::b#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta b
|
||||
jmp b1
|
||||
//SEG13 [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
|
||||
b1_from_b3:
|
||||
//SEG14 [5] phi (byte) main::b#2 = (byte) main::b#1 [phi:main::@3->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [6] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@3 -- vbuz1_eq_0_then_la1
|
||||
lda b
|
||||
cmp #0
|
||||
beq b3_from_b1
|
||||
jmp b2
|
||||
//SEG17 main::@2
|
||||
b2:
|
||||
//SEG18 [7] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5 -- vbuz1_eq_vbuc1_then_la1
|
||||
lda #1
|
||||
cmp b
|
||||
beq b5_from_b2
|
||||
//SEG19 [8] phi from main::@2 to main::@4 [phi:main::@2->main::@4]
|
||||
b4_from_b2:
|
||||
jmp b4
|
||||
//SEG20 main::@4
|
||||
b4:
|
||||
//SEG21 [9] phi from main::@4 to main::@5 [phi:main::@4->main::@5]
|
||||
b5_from_b4:
|
||||
//SEG22 [9] phi (byte~) main::$5 = (byte) 'c' [phi:main::@4->main::@5#0] -- vbuz1=vbuc1
|
||||
lda #'c'
|
||||
sta _5
|
||||
jmp b5
|
||||
//SEG23 [9] phi from main::@2 to main::@5 [phi:main::@2->main::@5]
|
||||
b5_from_b2:
|
||||
//SEG24 [9] phi (byte~) main::$5 = (byte) 'b' [phi:main::@2->main::@5#0] -- vbuz1=vbuc1
|
||||
lda #'b'
|
||||
sta _5
|
||||
jmp b5
|
||||
//SEG25 main::@5
|
||||
b5:
|
||||
//SEG26 [10] phi from main::@5 to main::@3 [phi:main::@5->main::@3]
|
||||
b3_from_b5:
|
||||
//SEG27 [10] phi (byte~) main::$7 = (byte~) main::$5 [phi:main::@5->main::@3#0] -- register_copy
|
||||
jmp b3
|
||||
//SEG28 [10] phi from main::@1 to main::@3 [phi:main::@1->main::@3]
|
||||
b3_from_b1:
|
||||
//SEG29 [10] phi (byte~) main::$7 = (byte) 'a' [phi:main::@1->main::@3#0] -- vbuz1=vbuc1
|
||||
lda #'a'
|
||||
sta _7
|
||||
jmp b3
|
||||
//SEG30 main::@3
|
||||
b3:
|
||||
//SEG31 [11] *((const byte*) main::SCREEN#0) ← (byte~) main::$7 -- _deref_pbuc1=vbuz1
|
||||
lda _7
|
||||
sta SCREEN
|
||||
//SEG32 [12] (byte) main::b#1 ← ++ (byte) main::b#2 -- vbuz1=_inc_vbuz1
|
||||
inc b
|
||||
//SEG33 [13] if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #3
|
||||
cmp b
|
||||
bne b1_from_b3
|
||||
jmp breturn
|
||||
//SEG34 main::@return
|
||||
breturn:
|
||||
//SEG35 [14] return
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Potential registers zp ZP_BYTE:2 [ main::b#2 main::b#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:3 [ main::$7 main::$5 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 33: zp ZP_BYTE:3 [ main::$7 main::$5 ] 22.79: zp ZP_BYTE:2 [ main::b#2 main::b#1 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 563 combination reg byte a [ main::$7 main::$5 ] reg byte x [ main::b#2 main::b#1 ]
|
||||
Uplifting [] best 563 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Demonstrates error with nested ternary operator
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG12 [5] phi (byte) main::b#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp b1
|
||||
//SEG13 [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
|
||||
b1_from_b3:
|
||||
//SEG14 [5] phi (byte) main::b#2 = (byte) main::b#1 [phi:main::@3->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [6] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@3 -- vbuxx_eq_0_then_la1
|
||||
cpx #0
|
||||
beq b3_from_b1
|
||||
jmp b2
|
||||
//SEG17 main::@2
|
||||
b2:
|
||||
//SEG18 [7] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5 -- vbuxx_eq_vbuc1_then_la1
|
||||
cpx #1
|
||||
beq b5_from_b2
|
||||
//SEG19 [8] phi from main::@2 to main::@4 [phi:main::@2->main::@4]
|
||||
b4_from_b2:
|
||||
jmp b4
|
||||
//SEG20 main::@4
|
||||
b4:
|
||||
//SEG21 [9] phi from main::@4 to main::@5 [phi:main::@4->main::@5]
|
||||
b5_from_b4:
|
||||
//SEG22 [9] phi (byte~) main::$5 = (byte) 'c' [phi:main::@4->main::@5#0] -- vbuaa=vbuc1
|
||||
lda #'c'
|
||||
jmp b5
|
||||
//SEG23 [9] phi from main::@2 to main::@5 [phi:main::@2->main::@5]
|
||||
b5_from_b2:
|
||||
//SEG24 [9] phi (byte~) main::$5 = (byte) 'b' [phi:main::@2->main::@5#0] -- vbuaa=vbuc1
|
||||
lda #'b'
|
||||
jmp b5
|
||||
//SEG25 main::@5
|
||||
b5:
|
||||
//SEG26 [10] phi from main::@5 to main::@3 [phi:main::@5->main::@3]
|
||||
b3_from_b5:
|
||||
//SEG27 [10] phi (byte~) main::$7 = (byte~) main::$5 [phi:main::@5->main::@3#0] -- register_copy
|
||||
jmp b3
|
||||
//SEG28 [10] phi from main::@1 to main::@3 [phi:main::@1->main::@3]
|
||||
b3_from_b1:
|
||||
//SEG29 [10] phi (byte~) main::$7 = (byte) 'a' [phi:main::@1->main::@3#0] -- vbuaa=vbuc1
|
||||
lda #'a'
|
||||
jmp b3
|
||||
//SEG30 main::@3
|
||||
b3:
|
||||
//SEG31 [11] *((const byte*) main::SCREEN#0) ← (byte~) main::$7 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
//SEG32 [12] (byte) main::b#1 ← ++ (byte) main::b#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG33 [13] if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #3
|
||||
bne b1_from_b3
|
||||
jmp breturn
|
||||
//SEG34 main::@return
|
||||
breturn:
|
||||
//SEG35 [14] return
|
||||
rts
|
||||
}
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp b4
|
||||
Removing instruction jmp b5
|
||||
Removing instruction jmp b3
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
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 b4_from_b2:
|
||||
Removing instruction b5_from_b4:
|
||||
Removing instruction b3_from_b5:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction b1_from_main:
|
||||
Removing instruction b2:
|
||||
Removing instruction b4:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Skipping double jump to b3 in jmp b5
|
||||
Succesful ASM optimization Pass5DoubleJumpElimination
|
||||
Relabelling long label b5_from_b2 to b2
|
||||
Relabelling long label b3_from_b1 to b4
|
||||
Succesful ASM optimization Pass5RelabelLongLabels
|
||||
Removing instruction jmp b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Removing instruction b5:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(byte~) main::$5 reg byte a 11.0
|
||||
(byte~) main::$7 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
(byte) main::b
|
||||
(byte) main::b#1 reg byte x 16.5
|
||||
(byte) main::b#2 reg byte x 6.285714285714286
|
||||
|
||||
reg byte x [ main::b#2 main::b#1 ]
|
||||
reg byte a [ main::$7 main::$5 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 341
|
||||
|
||||
//SEG0 File Comments
|
||||
// Demonstrates error with nested ternary operator
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG9 @end
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
//SEG12 [5] phi (byte) main::b#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
//SEG13 [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
|
||||
//SEG14 [5] phi (byte) main::b#2 = (byte) main::b#1 [phi:main::@3->main::@1#0] -- register_copy
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [6] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@3 -- vbuxx_eq_0_then_la1
|
||||
cpx #0
|
||||
beq b4
|
||||
//SEG17 main::@2
|
||||
//SEG18 [7] if((byte) main::b#2==(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@5 -- vbuxx_eq_vbuc1_then_la1
|
||||
cpx #1
|
||||
beq b2
|
||||
//SEG19 [8] phi from main::@2 to main::@4 [phi:main::@2->main::@4]
|
||||
//SEG20 main::@4
|
||||
//SEG21 [9] phi from main::@4 to main::@5 [phi:main::@4->main::@5]
|
||||
//SEG22 [9] phi (byte~) main::$5 = (byte) 'c' [phi:main::@4->main::@5#0] -- vbuaa=vbuc1
|
||||
lda #'c'
|
||||
jmp b3
|
||||
//SEG23 [9] phi from main::@2 to main::@5 [phi:main::@2->main::@5]
|
||||
b2:
|
||||
//SEG24 [9] phi (byte~) main::$5 = (byte) 'b' [phi:main::@2->main::@5#0] -- vbuaa=vbuc1
|
||||
lda #'b'
|
||||
//SEG25 main::@5
|
||||
//SEG26 [10] phi from main::@5 to main::@3 [phi:main::@5->main::@3]
|
||||
//SEG27 [10] phi (byte~) main::$7 = (byte~) main::$5 [phi:main::@5->main::@3#0] -- register_copy
|
||||
jmp b3
|
||||
//SEG28 [10] phi from main::@1 to main::@3 [phi:main::@1->main::@3]
|
||||
b4:
|
||||
//SEG29 [10] phi (byte~) main::$7 = (byte) 'a' [phi:main::@1->main::@3#0] -- vbuaa=vbuc1
|
||||
lda #'a'
|
||||
//SEG30 main::@3
|
||||
b3:
|
||||
//SEG31 [11] *((const byte*) main::SCREEN#0) ← (byte~) main::$7 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
//SEG32 [12] (byte) main::b#1 ← ++ (byte) main::b#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG33 [13] if((byte) main::b#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #3
|
||||
bne b1
|
||||
//SEG34 main::@return
|
||||
//SEG35 [14] return
|
||||
rts
|
||||
}
|
||||
|
20
src/test/ref/sandbox-ternary-error.sym
Normal file
20
src/test/ref/sandbox-ternary-error.sym
Normal file
@ -0,0 +1,20 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(byte~) main::$5 reg byte a 11.0
|
||||
(byte~) main::$7 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
|
||||
(byte) main::b
|
||||
(byte) main::b#1 reg byte x 16.5
|
||||
(byte) main::b#2 reg byte x 6.285714285714286
|
||||
|
||||
reg byte x [ main::b#2 main::b#1 ]
|
||||
reg byte a [ main::$7 main::$5 ]
|
726
src/test/ref/sandbox.asm
Normal file
726
src/test/ref/sandbox.asm
Normal file
@ -0,0 +1,726 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label zp1 = $61
|
||||
// #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169
|
||||
.label zp2 = $62
|
||||
.label TIMEHI = $a1
|
||||
.label TIMELO = $a2
|
||||
.label VICBANK = $d018
|
||||
main: {
|
||||
.label _2 = 6
|
||||
.label _3 = 6
|
||||
.label _4 = 8
|
||||
.label _11 = 6
|
||||
.label _12 = 6
|
||||
.label _13 = 8
|
||||
.label v = 4
|
||||
.label u = 2
|
||||
lda #$17
|
||||
sta VICBANK
|
||||
lda #0
|
||||
sta zp1
|
||||
lda #<$6e85
|
||||
sta u
|
||||
lda #>$6e85
|
||||
sta u+1
|
||||
b1:
|
||||
lda #0
|
||||
sta TIMEHI
|
||||
sta TIMELO
|
||||
sta zp2
|
||||
b2:
|
||||
jsr div16u
|
||||
inc zp2
|
||||
lda zp2
|
||||
cmp #$c8
|
||||
bcc b2
|
||||
lda TIMEHI
|
||||
sta _2
|
||||
lda #0
|
||||
sta _2+1
|
||||
ldy #8
|
||||
cpy #0
|
||||
beq !e+
|
||||
!:
|
||||
asl _3
|
||||
rol _3+1
|
||||
dey
|
||||
bne !-
|
||||
!e:
|
||||
lda TIMELO
|
||||
sta _4
|
||||
lda #0
|
||||
sta _4+1
|
||||
lda myprintf.w3
|
||||
clc
|
||||
adc _4
|
||||
sta myprintf.w3
|
||||
lda myprintf.w3+1
|
||||
adc _4+1
|
||||
sta myprintf.w3+1
|
||||
lda #<str
|
||||
sta myprintf.str
|
||||
lda #>str
|
||||
sta myprintf.str+1
|
||||
jsr myprintf
|
||||
jsr Print
|
||||
lda u
|
||||
sec
|
||||
sbc #<$4d2
|
||||
sta u
|
||||
lda u+1
|
||||
sbc #>$4d2
|
||||
sta u+1
|
||||
inc zp1
|
||||
lda zp1
|
||||
cmp #$a
|
||||
bcc b1
|
||||
lda #0
|
||||
sta zp1
|
||||
lda #<$6e85
|
||||
sta u
|
||||
lda #>$6e85
|
||||
sta u+1
|
||||
b5:
|
||||
lda #0
|
||||
sta TIMEHI
|
||||
sta TIMELO
|
||||
sta zp2
|
||||
b6:
|
||||
jsr div10
|
||||
inc zp2
|
||||
lda zp2
|
||||
cmp #$c8
|
||||
bcc b6
|
||||
lda TIMEHI
|
||||
sta _11
|
||||
lda #0
|
||||
sta _11+1
|
||||
ldy #8
|
||||
cpy #0
|
||||
beq !e+
|
||||
!:
|
||||
asl _12
|
||||
rol _12+1
|
||||
dey
|
||||
bne !-
|
||||
!e:
|
||||
lda TIMELO
|
||||
sta _13
|
||||
lda #0
|
||||
sta _13+1
|
||||
lda myprintf.w3
|
||||
clc
|
||||
adc _13
|
||||
sta myprintf.w3
|
||||
lda myprintf.w3+1
|
||||
adc _13+1
|
||||
sta myprintf.w3+1
|
||||
lda #<str1
|
||||
sta myprintf.str
|
||||
lda #>str1
|
||||
sta myprintf.str+1
|
||||
jsr myprintf
|
||||
jsr Print
|
||||
lda u
|
||||
sec
|
||||
sbc #<$4d2
|
||||
sta u
|
||||
lda u+1
|
||||
sbc #>$4d2
|
||||
sta u+1
|
||||
inc zp1
|
||||
lda zp1
|
||||
cmp #$a
|
||||
bcc b5
|
||||
rts
|
||||
str: .text "200 DIV16U: %5d,%4d IN %04d FRAMESm@"
|
||||
str1: .text "200 DIV10 : %5d,%4d IN %04d FRAMESm@"
|
||||
}
|
||||
Print: {
|
||||
// can this assembly be placed in a separate file and call it from the C code here?
|
||||
ldy #0
|
||||
loop:
|
||||
lda strTemp,y
|
||||
beq done
|
||||
jsr $ffd2
|
||||
iny
|
||||
jmp loop
|
||||
done:
|
||||
rts
|
||||
}
|
||||
// myprintf(byte* zeropage(8) str, word zeropage(2) w1, word zeropage(4) w2, word zeropage(6) w3)
|
||||
myprintf: {
|
||||
.label _17 = $12
|
||||
.label str = 8
|
||||
.label bDigits = $11
|
||||
.label bLen = $10
|
||||
.label digit = $a
|
||||
.label bArg = $b
|
||||
.label return = $10
|
||||
.label w1 = 2
|
||||
.label w2 = 4
|
||||
.label w3 = 6
|
||||
.label bFormat = $a
|
||||
.label w = $c
|
||||
.label bTrailing = $e
|
||||
.label bLeadZero = $f
|
||||
lda #0
|
||||
sta bLeadZero
|
||||
sta bDigits
|
||||
sta bTrailing
|
||||
sta w
|
||||
sta w+1
|
||||
sta bLen
|
||||
sta bArg
|
||||
sta bFormat
|
||||
b1:
|
||||
ldy #0
|
||||
lda (str),y
|
||||
tax
|
||||
lda bFormat
|
||||
cmp #0
|
||||
bne !b2+
|
||||
jmp b2
|
||||
!b2:
|
||||
cpx #'0'
|
||||
bne b3
|
||||
lda #1
|
||||
sta bLeadZero
|
||||
b27:
|
||||
inc str
|
||||
bne !+
|
||||
inc str+1
|
||||
!:
|
||||
ldy #0
|
||||
lda (str),y
|
||||
cmp #0
|
||||
bne b1
|
||||
tya
|
||||
ldy return
|
||||
sta strTemp,y
|
||||
rts
|
||||
b3:
|
||||
cpx #'1'
|
||||
bcc !b37+
|
||||
jmp b37
|
||||
!b37:
|
||||
b4:
|
||||
cpx #'-'
|
||||
bne b5
|
||||
lda #1
|
||||
sta bTrailing
|
||||
jmp b27
|
||||
b5:
|
||||
cpx #'c'
|
||||
bne !b6+
|
||||
jmp b6
|
||||
!b6:
|
||||
cpx #'d'
|
||||
beq b7
|
||||
cpx #'x'
|
||||
beq b26
|
||||
cpx #'X'
|
||||
beq b26
|
||||
b22:
|
||||
lda #0
|
||||
sta bFormat
|
||||
jmp b27
|
||||
b26:
|
||||
lda w+1
|
||||
sta _17+1
|
||||
lda w
|
||||
sta _17
|
||||
ldy #4
|
||||
!:
|
||||
lsr _17+1
|
||||
ror _17
|
||||
dey
|
||||
bne !-
|
||||
lda _17
|
||||
and #$f
|
||||
tax
|
||||
cpx #$a
|
||||
bcc b8
|
||||
lda #$57
|
||||
jmp b9
|
||||
b8:
|
||||
lda #'0'
|
||||
b9:
|
||||
stx $ff
|
||||
clc
|
||||
adc $ff
|
||||
ldy bLen
|
||||
sta strTemp,y
|
||||
iny
|
||||
lda w
|
||||
and #$f
|
||||
tax
|
||||
cpx #$a
|
||||
bcc b10
|
||||
lda #$57
|
||||
jmp b11
|
||||
b10:
|
||||
lda #'0'
|
||||
b11:
|
||||
stx $ff
|
||||
clc
|
||||
adc $ff
|
||||
sta strTemp,y
|
||||
iny
|
||||
sty bLen
|
||||
jmp b22
|
||||
b7:
|
||||
lda w
|
||||
sta utoa.value
|
||||
lda w+1
|
||||
sta utoa.value+1
|
||||
jsr utoa
|
||||
ldx #1
|
||||
b12:
|
||||
lda buf6,x
|
||||
cmp #0
|
||||
bne b13
|
||||
lda bTrailing
|
||||
cmp #0
|
||||
beq b39
|
||||
b15:
|
||||
lda #0
|
||||
sta digit
|
||||
b19:
|
||||
ldy digit
|
||||
lda buf6,y
|
||||
ldy bLen
|
||||
sta strTemp,y
|
||||
inc bLen
|
||||
inc digit
|
||||
txa
|
||||
cmp digit
|
||||
beq !+
|
||||
bcs b19
|
||||
!:
|
||||
lda bTrailing
|
||||
cmp #0
|
||||
bne b40
|
||||
jmp b22
|
||||
b40:
|
||||
cpx bDigits
|
||||
bcc b21
|
||||
jmp b22
|
||||
b21:
|
||||
lda #' '
|
||||
ldy bLen
|
||||
sta strTemp,y
|
||||
inc bLen
|
||||
dec bDigits
|
||||
cpx bDigits
|
||||
bcc b21
|
||||
jmp b22
|
||||
b39:
|
||||
cpx bDigits
|
||||
bcc b16
|
||||
jmp b15
|
||||
b16:
|
||||
lda bLeadZero
|
||||
cmp #0
|
||||
beq b14
|
||||
lda #'0'
|
||||
jmp b18
|
||||
b14:
|
||||
lda #' '
|
||||
b18:
|
||||
ldy bLen
|
||||
sta strTemp,y
|
||||
inc bLen
|
||||
dec bDigits
|
||||
cpx bDigits
|
||||
bcc b16
|
||||
jmp b15
|
||||
b13:
|
||||
inx
|
||||
jmp b12
|
||||
b6:
|
||||
lda w
|
||||
// "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170
|
||||
ldy bLen
|
||||
sta strTemp,y
|
||||
inc bLen
|
||||
jmp b22
|
||||
b37:
|
||||
cpx #'9'
|
||||
bcc b23
|
||||
beq b23
|
||||
jmp b4
|
||||
b23:
|
||||
txa
|
||||
axs #'0'
|
||||
stx bDigits
|
||||
jmp b27
|
||||
b2:
|
||||
cpx #'%'
|
||||
bne b28
|
||||
// default format
|
||||
//w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 [FIXED]
|
||||
lda bArg
|
||||
cmp #0
|
||||
beq b42
|
||||
lda #1
|
||||
cmp bArg
|
||||
beq b43
|
||||
lda w3
|
||||
sta w
|
||||
lda w3+1
|
||||
sta w+1
|
||||
b29:
|
||||
inc bArg
|
||||
lda #0
|
||||
sta bLeadZero
|
||||
lda #1
|
||||
sta bDigits
|
||||
lda #0
|
||||
sta bTrailing
|
||||
lda #1
|
||||
sta bFormat
|
||||
jmp b27
|
||||
b43:
|
||||
lda w2
|
||||
sta w
|
||||
lda w2+1
|
||||
sta w+1
|
||||
jmp b29
|
||||
b42:
|
||||
lda w1
|
||||
sta w
|
||||
lda w1+1
|
||||
sta w+1
|
||||
jmp b29
|
||||
b28:
|
||||
cpx #$41
|
||||
bcs b41
|
||||
b30:
|
||||
// swap 0x41 / 0x61 when in lower case mode
|
||||
ldy bLen
|
||||
txa
|
||||
sta strTemp,y
|
||||
inc bLen
|
||||
jmp b27
|
||||
b41:
|
||||
cpx #$5a+1
|
||||
bcc b35
|
||||
jmp b30
|
||||
b35:
|
||||
txa
|
||||
axs #-[$20]
|
||||
jmp b30
|
||||
buf6: .fill 6, 0
|
||||
}
|
||||
// utoa(word zeropage($12) value, byte* zeropage($14) dst)
|
||||
utoa: {
|
||||
.label value = $12
|
||||
.label dst = $14
|
||||
lda value+1
|
||||
cmp #>$2710
|
||||
bcc !+
|
||||
beq !b5+
|
||||
jmp b5
|
||||
!b5:
|
||||
lda value
|
||||
cmp #<$2710
|
||||
bcc !b5+
|
||||
jmp b5
|
||||
!b5:
|
||||
!:
|
||||
lda #<myprintf.buf6
|
||||
sta dst
|
||||
lda #>myprintf.buf6
|
||||
sta dst+1
|
||||
ldx #0
|
||||
b1:
|
||||
cpx #1
|
||||
beq b6
|
||||
lda value+1
|
||||
cmp #>$3e8
|
||||
bcc !+
|
||||
bne b6
|
||||
lda value
|
||||
cmp #<$3e8
|
||||
bcs b6
|
||||
!:
|
||||
b2:
|
||||
cpx #1
|
||||
beq b7
|
||||
lda value+1
|
||||
cmp #>$64
|
||||
bcc !+
|
||||
bne b7
|
||||
lda value
|
||||
cmp #<$64
|
||||
bcs b7
|
||||
!:
|
||||
b3:
|
||||
cpx #1
|
||||
beq b8
|
||||
lda value+1
|
||||
cmp #>$a
|
||||
bcc !+
|
||||
bne b8
|
||||
lda value
|
||||
cmp #<$a
|
||||
bcs b8
|
||||
!:
|
||||
b4:
|
||||
lda value
|
||||
clc
|
||||
adc #'0'
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
lda #0
|
||||
tay
|
||||
sta (dst),y
|
||||
rts
|
||||
b8:
|
||||
lda #$a
|
||||
sta append.sub
|
||||
lda #0
|
||||
sta append.sub+1
|
||||
jsr append
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
jmp b4
|
||||
b7:
|
||||
lda #$64
|
||||
sta append.sub
|
||||
lda #0
|
||||
sta append.sub+1
|
||||
jsr append
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
ldx #1
|
||||
jmp b3
|
||||
b6:
|
||||
lda #<$3e8
|
||||
sta append.sub
|
||||
lda #>$3e8
|
||||
sta append.sub+1
|
||||
jsr append
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
ldx #1
|
||||
jmp b2
|
||||
b5:
|
||||
lda #<$2710
|
||||
sta append.sub
|
||||
lda #>$2710
|
||||
sta append.sub+1
|
||||
lda #<myprintf.buf6
|
||||
sta append.dst
|
||||
lda #>myprintf.buf6
|
||||
sta append.dst+1
|
||||
jsr append
|
||||
lda #<myprintf.buf6+1
|
||||
sta dst
|
||||
lda #>myprintf.buf6+1
|
||||
sta dst+1
|
||||
ldx #1
|
||||
jmp b1
|
||||
}
|
||||
// simple 'utoa' without using multiply or divide
|
||||
// append(byte* zeropage($14) dst, word zeropage($12) value, word zeropage($16) sub)
|
||||
append: {
|
||||
.label value = $12
|
||||
.label return = $12
|
||||
.label dst = $14
|
||||
.label sub = $16
|
||||
lda #'0'
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
b1:
|
||||
lda sub+1
|
||||
cmp value+1
|
||||
bne !+
|
||||
lda sub
|
||||
cmp value
|
||||
!:
|
||||
bcc b2
|
||||
beq b2
|
||||
rts
|
||||
b2:
|
||||
ldy #0
|
||||
lda (dst),y
|
||||
clc
|
||||
adc #1
|
||||
sta (dst),y
|
||||
lda value
|
||||
sec
|
||||
sbc sub
|
||||
sta value
|
||||
lda value+1
|
||||
sbc sub+1
|
||||
sta value+1
|
||||
jmp b1
|
||||
}
|
||||
// div10(word zeropage(4) val)
|
||||
div10: {
|
||||
.label _0 = 4
|
||||
.label _2 = 6
|
||||
.label _3 = 4
|
||||
.label _4 = 6
|
||||
.label _5 = 6
|
||||
.label val = 4
|
||||
.label val_1 = 6
|
||||
.label return = 4
|
||||
.label val_4 = 2
|
||||
lda val_4+1
|
||||
lsr
|
||||
sta _0+1
|
||||
lda val_4
|
||||
ror
|
||||
sta _0
|
||||
inc val
|
||||
bne !+
|
||||
inc val+1
|
||||
!:
|
||||
lda val
|
||||
asl
|
||||
sta _2
|
||||
lda val+1
|
||||
rol
|
||||
sta _2+1
|
||||
lda val_1
|
||||
clc
|
||||
adc val
|
||||
sta val_1
|
||||
lda val_1+1
|
||||
adc val+1
|
||||
sta val_1+1
|
||||
sta _3+1
|
||||
lda val_1
|
||||
sta _3
|
||||
ldy #4
|
||||
!:
|
||||
lsr _3+1
|
||||
ror _3
|
||||
dey
|
||||
bne !-
|
||||
lda val
|
||||
clc
|
||||
adc val_1
|
||||
sta val
|
||||
lda val+1
|
||||
adc val_1+1
|
||||
sta val+1
|
||||
sta _4+1
|
||||
lda val
|
||||
sta _4
|
||||
ldy #4
|
||||
!:
|
||||
lsr _4+1
|
||||
ror _4
|
||||
dey
|
||||
bne !-
|
||||
ldy #4
|
||||
!:
|
||||
lsr _5+1
|
||||
ror _5
|
||||
dey
|
||||
bne !-
|
||||
lda val
|
||||
clc
|
||||
adc _5
|
||||
sta val
|
||||
lda val+1
|
||||
adc _5+1
|
||||
sta val+1
|
||||
ldy #4
|
||||
!:
|
||||
lsr return+1
|
||||
ror return
|
||||
dey
|
||||
bne !-
|
||||
rts
|
||||
}
|
||||
// Performs division on two 16 bit unsigned words
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// div16u(word zeropage(2) dividend)
|
||||
div16u: {
|
||||
.label divisor = $a
|
||||
.label return = 4
|
||||
.label dividend = 2
|
||||
lda dividend
|
||||
sta divr16u.dividend
|
||||
lda dividend+1
|
||||
sta divr16u.dividend+1
|
||||
jsr divr16u
|
||||
rts
|
||||
}
|
||||
// Performs division on two 16 bit unsigned words and an initial remainder
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The final remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// divr16u(word zeropage(8) dividend, word zeropage(6) rem)
|
||||
divr16u: {
|
||||
.label rem = 6
|
||||
.label dividend = 8
|
||||
.label quotient = 4
|
||||
.label return = 4
|
||||
ldx #0
|
||||
txa
|
||||
sta quotient
|
||||
sta quotient+1
|
||||
sta rem
|
||||
sta rem+1
|
||||
b1:
|
||||
asl rem
|
||||
rol rem+1
|
||||
lda dividend+1
|
||||
and #$80
|
||||
cmp #0
|
||||
beq b2
|
||||
lda #1
|
||||
ora rem
|
||||
sta rem
|
||||
b2:
|
||||
asl dividend
|
||||
rol dividend+1
|
||||
asl quotient
|
||||
rol quotient+1
|
||||
lda rem+1
|
||||
cmp #>div16u.divisor
|
||||
bcc b3
|
||||
bne !+
|
||||
lda rem
|
||||
cmp #<div16u.divisor
|
||||
bcc b3
|
||||
!:
|
||||
inc quotient
|
||||
bne !+
|
||||
inc quotient+1
|
||||
!:
|
||||
lda rem
|
||||
sec
|
||||
sbc #<div16u.divisor
|
||||
sta rem
|
||||
lda rem+1
|
||||
sbc #>div16u.divisor
|
||||
sta rem+1
|
||||
b3:
|
||||
inx
|
||||
cpx #$10
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162
|
||||
strTemp: .fill $64, 0
|
444
src/test/ref/sandbox.cfg
Normal file
444
src/test/ref/sandbox.cfg
Normal file
@ -0,0 +1,444 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] *((const byte*) VICBANK#0) ← (byte/signed byte/word/signed word/dword/signed dword) $17
|
||||
[5] *((const byte*) zp1#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@10
|
||||
[6] (word) main::u#11 ← phi( main/(word/signed word/dword/signed dword) $6e85 main::@10/(word) main::u#2 )
|
||||
[7] *((const byte*) TIMEHI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[8] *((const byte*) TIMELO#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[9] *((const byte*) zp2#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1 main::@8
|
||||
[10] (word) div16u::dividend#0 ← (word) main::u#11
|
||||
[11] call div16u
|
||||
[12] (word) div16u::return#2 ← (word) div16u::return#0
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@2
|
||||
[13] (word) main::v#1 ← (word) div16u::return#2
|
||||
[14] *((const byte*) zp2#0) ← ++ *((const byte*) zp2#0)
|
||||
[15] if(*((const byte*) zp2#0)<(byte/word/signed word/dword/signed dword) $c8) goto main::@2
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@8
|
||||
[16] (word~) main::$2 ← ((word)) *((const byte*) TIMEHI#0)
|
||||
[17] (word~) main::$3 ← (word~) main::$2 << (byte/signed byte/word/signed word/dword/signed dword) 8
|
||||
[18] (word~) main::$4 ← ((word)) *((const byte*) TIMELO#0)
|
||||
[19] (word) myprintf::w3#0 ← (word~) main::$3 + (word~) main::$4
|
||||
[20] (word) myprintf::w1#0 ← (word) main::u#11
|
||||
[21] (word) myprintf::w2#0 ← (word) main::v#1
|
||||
[22] call myprintf
|
||||
to:main::@9
|
||||
main::@9: scope:[main] from main::@3
|
||||
[23] phi()
|
||||
[24] call Print
|
||||
to:main::@10
|
||||
main::@10: scope:[main] from main::@9
|
||||
[25] (word) main::u#2 ← (word) main::u#11 - (word/signed word/dword/signed dword) $4d2
|
||||
[26] *((const byte*) zp1#0) ← ++ *((const byte*) zp1#0)
|
||||
[27] if(*((const byte*) zp1#0)<(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@10
|
||||
[28] *((const byte*) zp1#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@13 main::@4
|
||||
[29] (word) main::u#15 ← phi( main::@13/(word) main::u#4 main::@4/(word/signed word/dword/signed dword) $6e85 )
|
||||
[30] *((const byte*) TIMEHI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[31] *((const byte*) TIMELO#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[32] *((const byte*) zp2#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@11 main::@5
|
||||
[33] (word) div10::val#4 ← (word) main::u#15
|
||||
[34] call div10
|
||||
[35] (word) div10::return#2 ← (word) div10::return#0
|
||||
to:main::@11
|
||||
main::@11: scope:[main] from main::@6
|
||||
[36] (word) main::v#2 ← (word) div10::return#2
|
||||
[37] *((const byte*) zp2#0) ← ++ *((const byte*) zp2#0)
|
||||
[38] if(*((const byte*) zp2#0)<(byte/word/signed word/dword/signed dword) $c8) goto main::@6
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@11
|
||||
[39] (word~) main::$11 ← ((word)) *((const byte*) TIMEHI#0)
|
||||
[40] (word~) main::$12 ← (word~) main::$11 << (byte/signed byte/word/signed word/dword/signed dword) 8
|
||||
[41] (word~) main::$13 ← ((word)) *((const byte*) TIMELO#0)
|
||||
[42] (word) myprintf::w3#1 ← (word~) main::$12 + (word~) main::$13
|
||||
[43] (word) myprintf::w1#1 ← (word) main::u#15
|
||||
[44] (word) myprintf::w2#1 ← (word) main::v#2
|
||||
[45] call myprintf
|
||||
to:main::@12
|
||||
main::@12: scope:[main] from main::@7
|
||||
[46] phi()
|
||||
[47] call Print
|
||||
to:main::@13
|
||||
main::@13: scope:[main] from main::@12
|
||||
[48] (word) main::u#4 ← (word) main::u#15 - (word/signed word/dword/signed dword) $4d2
|
||||
[49] *((const byte*) zp1#0) ← ++ *((const byte*) zp1#0)
|
||||
[50] if(*((const byte*) zp1#0)<(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@5
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@13
|
||||
[51] return
|
||||
to:@return
|
||||
Print: scope:[Print] from main::@12 main::@9
|
||||
asm { ldy#0 loop: ldastrTemp,y beqdone jsr$FFD2 iny jmploop done: }
|
||||
to:Print::@return
|
||||
Print::@return: scope:[Print] from Print
|
||||
[53] return
|
||||
to:@return
|
||||
myprintf: scope:[myprintf] from main::@3 main::@7
|
||||
[54] (word) myprintf::w3#7 ← phi( main::@3/(word) myprintf::w3#0 main::@7/(word) myprintf::w3#1 )
|
||||
[54] (word) myprintf::w2#7 ← phi( main::@3/(word) myprintf::w2#0 main::@7/(word) myprintf::w2#1 )
|
||||
[54] (word) myprintf::w1#6 ← phi( main::@3/(word) myprintf::w1#0 main::@7/(word) myprintf::w1#1 )
|
||||
[54] (byte*) myprintf::str#5 ← phi( main::@3/(const string) main::str main::@7/(const string) main::str1 )
|
||||
to:myprintf::@1
|
||||
myprintf::@1: scope:[myprintf] from myprintf myprintf::@27
|
||||
[55] (byte) myprintf::bLeadZero#10 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(byte) myprintf::bLeadZero#18 )
|
||||
[55] (byte) myprintf::bDigits#14 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(byte) myprintf::bDigits#24 )
|
||||
[55] (byte) myprintf::bTrailing#10 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(byte) myprintf::bTrailing#21 )
|
||||
[55] (word) myprintf::w#10 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(word) myprintf::w#17 )
|
||||
[55] (byte) myprintf::bLen#14 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(byte) myprintf::return#0 )
|
||||
[55] (byte) myprintf::bArg#12 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(byte) myprintf::bArg#10 )
|
||||
[55] (byte) myprintf::bFormat#10 ← phi( myprintf/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@27/(byte) myprintf::bFormat#4 )
|
||||
[55] (byte*) myprintf::str#10 ← phi( myprintf/(byte*) myprintf::str#5 myprintf::@27/(byte*) myprintf::str#0 )
|
||||
[56] (byte) myprintf::b#1 ← *((byte*) myprintf::str#10)
|
||||
[57] if((byte) myprintf::bFormat#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@2
|
||||
to:myprintf::@31
|
||||
myprintf::@31: scope:[myprintf] from myprintf::@1
|
||||
[58] if((byte) myprintf::b#1!=(byte) '0') goto myprintf::@3
|
||||
to:myprintf::@27
|
||||
myprintf::@27: scope:[myprintf] from myprintf::@22 myprintf::@23 myprintf::@29 myprintf::@30 myprintf::@31 myprintf::@4
|
||||
[59] (byte) myprintf::bLeadZero#18 ← phi( myprintf::@22/(byte) myprintf::bLeadZero#10 myprintf::@23/(byte) myprintf::bLeadZero#10 myprintf::@4/(byte) myprintf::bLeadZero#10 myprintf::@29/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@30/(byte) myprintf::bLeadZero#10 myprintf::@31/(byte/signed byte/word/signed word/dword/signed dword) 1 )
|
||||
[59] (byte) myprintf::bDigits#24 ← phi( myprintf::@22/(byte) myprintf::bDigits#25 myprintf::@23/(byte) myprintf::bDigits#1 myprintf::@4/(byte) myprintf::bDigits#14 myprintf::@29/(byte/signed byte/word/signed word/dword/signed dword) 1 myprintf::@30/(byte) myprintf::bDigits#14 myprintf::@31/(byte) myprintf::bDigits#14 )
|
||||
[59] (byte) myprintf::bTrailing#21 ← phi( myprintf::@22/(byte) myprintf::bTrailing#10 myprintf::@23/(byte) myprintf::bTrailing#10 myprintf::@4/(byte/signed byte/word/signed word/dword/signed dword) 1 myprintf::@29/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@30/(byte) myprintf::bTrailing#10 myprintf::@31/(byte) myprintf::bTrailing#10 )
|
||||
[59] (word) myprintf::w#17 ← phi( myprintf::@22/(word) myprintf::w#10 myprintf::@23/(word) myprintf::w#10 myprintf::@4/(word) myprintf::w#10 myprintf::@29/(word) myprintf::w#21 myprintf::@30/(word) myprintf::w#10 myprintf::@31/(word) myprintf::w#10 )
|
||||
[59] (byte) myprintf::bArg#10 ← phi( myprintf::@22/(byte) myprintf::bArg#12 myprintf::@23/(byte) myprintf::bArg#12 myprintf::@4/(byte) myprintf::bArg#12 myprintf::@29/(byte) myprintf::bArg#1 myprintf::@30/(byte) myprintf::bArg#12 myprintf::@31/(byte) myprintf::bArg#12 )
|
||||
[59] (byte) myprintf::return#0 ← phi( myprintf::@22/(byte) myprintf::bLen#28 myprintf::@23/(byte) myprintf::bLen#14 myprintf::@4/(byte) myprintf::bLen#14 myprintf::@29/(byte) myprintf::bLen#14 myprintf::@30/(byte) myprintf::bLen#7 myprintf::@31/(byte) myprintf::bLen#14 )
|
||||
[59] (byte) myprintf::bFormat#4 ← phi( myprintf::@22/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@23/(byte) myprintf::bFormat#10 myprintf::@4/(byte) myprintf::bFormat#10 myprintf::@29/(byte/signed byte/word/signed word/dword/signed dword) 1 myprintf::@30/(byte) myprintf::bFormat#10 myprintf::@31/(byte) myprintf::bFormat#10 )
|
||||
[60] (byte*) myprintf::str#0 ← ++ (byte*) myprintf::str#10
|
||||
[61] if(*((byte*) myprintf::str#0)!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@1
|
||||
to:myprintf::@36
|
||||
myprintf::@36: scope:[myprintf] from myprintf::@27
|
||||
[62] *((const byte[$64]) strTemp#0 + (byte) myprintf::return#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:myprintf::@return
|
||||
myprintf::@return: scope:[myprintf] from myprintf::@36
|
||||
[63] return
|
||||
to:@return
|
||||
myprintf::@3: scope:[myprintf] from myprintf::@31
|
||||
[64] if((byte) myprintf::b#1>=(byte) '1') goto myprintf::@37
|
||||
to:myprintf::@4
|
||||
myprintf::@4: scope:[myprintf] from myprintf::@3 myprintf::@37
|
||||
[65] if((byte) myprintf::b#1!=(byte) '-') goto myprintf::@5
|
||||
to:myprintf::@27
|
||||
myprintf::@5: scope:[myprintf] from myprintf::@4
|
||||
[66] if((byte) myprintf::b#1==(byte) 'c') goto myprintf::@6
|
||||
to:myprintf::@24
|
||||
myprintf::@24: scope:[myprintf] from myprintf::@5
|
||||
[67] if((byte) myprintf::b#1==(byte) 'd') goto myprintf::@7
|
||||
to:myprintf::@25
|
||||
myprintf::@25: scope:[myprintf] from myprintf::@24
|
||||
[68] if((byte) myprintf::b#1==(byte) 'x') goto myprintf::@26
|
||||
to:myprintf::@38
|
||||
myprintf::@38: scope:[myprintf] from myprintf::@25
|
||||
[69] if((byte) myprintf::b#1==(byte) 'X') goto myprintf::@26
|
||||
to:myprintf::@22
|
||||
myprintf::@22: scope:[myprintf] from myprintf::@11 myprintf::@20 myprintf::@21 myprintf::@38 myprintf::@40 myprintf::@6
|
||||
[70] (byte) myprintf::bDigits#25 ← phi( myprintf::@11/(byte) myprintf::bDigits#14 myprintf::@20/(byte) myprintf::bDigits#16 myprintf::@21/(byte) myprintf::bDigits#3 myprintf::@6/(byte) myprintf::bDigits#14 myprintf::@38/(byte) myprintf::bDigits#14 myprintf::@40/(byte) myprintf::bDigits#16 )
|
||||
[70] (byte) myprintf::bLen#28 ← phi( myprintf::@11/(byte) myprintf::bLen#3 myprintf::@20/(byte) myprintf::bLen#24 myprintf::@21/(byte) myprintf::bLen#6 myprintf::@6/(byte) myprintf::bLen#1 myprintf::@38/(byte) myprintf::bLen#14 myprintf::@40/(byte) myprintf::bLen#24 )
|
||||
to:myprintf::@27
|
||||
myprintf::@26: scope:[myprintf] from myprintf::@25 myprintf::@38
|
||||
[71] (word~) myprintf::$17 ← (word) myprintf::w#10 >> (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
[72] (byte) myprintf::b#15 ← (word~) myprintf::$17 & (byte/signed byte/word/signed word/dword/signed dword) $f
|
||||
[73] if((byte) myprintf::b#15<(byte/signed byte/word/signed word/dword/signed dword) $a) goto myprintf::@9
|
||||
to:myprintf::@8
|
||||
myprintf::@8: scope:[myprintf] from myprintf::@26
|
||||
[74] phi()
|
||||
to:myprintf::@9
|
||||
myprintf::@9: scope:[myprintf] from myprintf::@26 myprintf::@8
|
||||
[75] (byte~) myprintf::$22 ← phi( myprintf::@26/(byte) '0' myprintf::@8/(byte/signed byte/word/signed word/dword/signed dword) $57 )
|
||||
[76] (byte~) myprintf::$23 ← (byte~) myprintf::$22 + (byte) myprintf::b#15
|
||||
[77] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#14) ← (byte~) myprintf::$23
|
||||
[78] (byte) myprintf::bLen#10 ← ++ (byte) myprintf::bLen#14
|
||||
[79] (byte) myprintf::b#16 ← (word) myprintf::w#10 & (byte/signed byte/word/signed word/dword/signed dword) $f
|
||||
[80] if((byte) myprintf::b#16<(byte/signed byte/word/signed word/dword/signed dword) $a) goto myprintf::@11
|
||||
to:myprintf::@10
|
||||
myprintf::@10: scope:[myprintf] from myprintf::@9
|
||||
[81] phi()
|
||||
to:myprintf::@11
|
||||
myprintf::@11: scope:[myprintf] from myprintf::@10 myprintf::@9
|
||||
[82] (byte~) myprintf::$28 ← phi( myprintf::@9/(byte) '0' myprintf::@10/(byte/signed byte/word/signed word/dword/signed dword) $57 )
|
||||
[83] (byte~) myprintf::$29 ← (byte~) myprintf::$28 + (byte) myprintf::b#16
|
||||
[84] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#10) ← (byte~) myprintf::$29
|
||||
[85] (byte) myprintf::bLen#3 ← ++ (byte) myprintf::bLen#10
|
||||
to:myprintf::@22
|
||||
myprintf::@7: scope:[myprintf] from myprintf::@24
|
||||
[86] (word) utoa::value#4 ← (word) myprintf::w#10
|
||||
[87] call utoa
|
||||
to:myprintf::@12
|
||||
myprintf::@12: scope:[myprintf] from myprintf::@13 myprintf::@7
|
||||
[88] (byte) myprintf::b#17 ← phi( myprintf::@13/(byte) myprintf::b#5 myprintf::@7/(byte/signed byte/word/signed word/dword/signed dword) 1 )
|
||||
[89] if(*((const byte[6]) myprintf::buf6#0 + (byte) myprintf::b#17)!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@13
|
||||
to:myprintf::@14
|
||||
myprintf::@14: scope:[myprintf] from myprintf::@12
|
||||
[90] if((byte) myprintf::bTrailing#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@39
|
||||
to:myprintf::@15
|
||||
myprintf::@15: scope:[myprintf] from myprintf::@14 myprintf::@18 myprintf::@39
|
||||
[91] (byte) myprintf::bDigits#16 ← phi( myprintf::@14/(byte) myprintf::bDigits#14 myprintf::@18/(byte) myprintf::bDigits#2 )
|
||||
[91] (byte) myprintf::bLen#23 ← phi( myprintf::@14/(byte) myprintf::bLen#14 myprintf::@18/(byte) myprintf::bLen#4 )
|
||||
to:myprintf::@19
|
||||
myprintf::@19: scope:[myprintf] from myprintf::@15 myprintf::@19
|
||||
[92] (byte) myprintf::bLen#12 ← phi( myprintf::@15/(byte) myprintf::bLen#23 myprintf::@19/(byte) myprintf::bLen#24 )
|
||||
[92] (byte) myprintf::digit#3 ← phi( myprintf::@15/(byte/signed byte/word/signed word/dword/signed dword) 0 myprintf::@19/(byte) myprintf::digit#2 )
|
||||
[93] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#12) ← *((const byte[6]) myprintf::buf6#0 + (byte) myprintf::digit#3)
|
||||
[94] (byte) myprintf::bLen#24 ← ++ (byte) myprintf::bLen#12
|
||||
[95] (byte) myprintf::digit#2 ← ++ (byte) myprintf::digit#3
|
||||
[96] if((byte) myprintf::digit#2<(byte) myprintf::b#17) goto myprintf::@19
|
||||
to:myprintf::@20
|
||||
myprintf::@20: scope:[myprintf] from myprintf::@19
|
||||
[97] if((byte) myprintf::bTrailing#10!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@40
|
||||
to:myprintf::@22
|
||||
myprintf::@40: scope:[myprintf] from myprintf::@20
|
||||
[98] if((byte) myprintf::bDigits#16>(byte) myprintf::b#17) goto myprintf::@21
|
||||
to:myprintf::@22
|
||||
myprintf::@21: scope:[myprintf] from myprintf::@21 myprintf::@40
|
||||
[99] (byte) myprintf::bDigits#8 ← phi( myprintf::@40/(byte) myprintf::bDigits#16 myprintf::@21/(byte) myprintf::bDigits#3 )
|
||||
[99] (byte) myprintf::bLen#13 ← phi( myprintf::@40/(byte) myprintf::bLen#24 myprintf::@21/(byte) myprintf::bLen#6 )
|
||||
[100] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#13) ← (byte) ' '
|
||||
[101] (byte) myprintf::bLen#6 ← ++ (byte) myprintf::bLen#13
|
||||
[102] (byte) myprintf::bDigits#3 ← -- (byte) myprintf::bDigits#8
|
||||
[103] if((byte) myprintf::bDigits#3>(byte) myprintf::b#17) goto myprintf::@21
|
||||
to:myprintf::@22
|
||||
myprintf::@39: scope:[myprintf] from myprintf::@14
|
||||
[104] if((byte) myprintf::bDigits#14>(byte) myprintf::b#17) goto myprintf::@16
|
||||
to:myprintf::@15
|
||||
myprintf::@16: scope:[myprintf] from myprintf::@18 myprintf::@39
|
||||
[105] (byte) myprintf::bDigits#10 ← phi( myprintf::@39/(byte) myprintf::bDigits#14 myprintf::@18/(byte) myprintf::bDigits#2 )
|
||||
[105] (byte) myprintf::bLen#11 ← phi( myprintf::@39/(byte) myprintf::bLen#14 myprintf::@18/(byte) myprintf::bLen#4 )
|
||||
[106] if((byte) myprintf::bLeadZero#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@18
|
||||
to:myprintf::@17
|
||||
myprintf::@17: scope:[myprintf] from myprintf::@16
|
||||
[107] phi()
|
||||
to:myprintf::@18
|
||||
myprintf::@18: scope:[myprintf] from myprintf::@16 myprintf::@17
|
||||
[108] (byte~) myprintf::$39 ← phi( myprintf::@16/(byte) ' ' myprintf::@17/(byte) '0' )
|
||||
[109] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#11) ← (byte~) myprintf::$39
|
||||
[110] (byte) myprintf::bLen#4 ← ++ (byte) myprintf::bLen#11
|
||||
[111] (byte) myprintf::bDigits#2 ← -- (byte) myprintf::bDigits#10
|
||||
[112] if((byte) myprintf::bDigits#2>(byte) myprintf::b#17) goto myprintf::@16
|
||||
to:myprintf::@15
|
||||
myprintf::@13: scope:[myprintf] from myprintf::@12
|
||||
[113] (byte) myprintf::b#5 ← ++ (byte) myprintf::b#17
|
||||
to:myprintf::@12
|
||||
myprintf::@6: scope:[myprintf] from myprintf::@5
|
||||
[114] (byte~) myprintf::$47 ← ((byte)) (word) myprintf::w#10
|
||||
[115] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#14) ← (byte~) myprintf::$47
|
||||
[116] (byte) myprintf::bLen#1 ← ++ (byte) myprintf::bLen#14
|
||||
to:myprintf::@22
|
||||
myprintf::@37: scope:[myprintf] from myprintf::@3
|
||||
[117] if((byte) myprintf::b#1<=(byte) '9') goto myprintf::@23
|
||||
to:myprintf::@4
|
||||
myprintf::@23: scope:[myprintf] from myprintf::@37
|
||||
[118] (byte) myprintf::bDigits#1 ← (byte) myprintf::b#1 - (byte) '0'
|
||||
to:myprintf::@27
|
||||
myprintf::@2: scope:[myprintf] from myprintf::@1
|
||||
[119] if((byte) myprintf::b#1!=(byte) '%') goto myprintf::@28
|
||||
to:myprintf::@32
|
||||
myprintf::@32: scope:[myprintf] from myprintf::@2
|
||||
[120] if((byte) myprintf::bArg#12==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@42
|
||||
to:myprintf::@33
|
||||
myprintf::@33: scope:[myprintf] from myprintf::@32
|
||||
[121] if((byte) myprintf::bArg#12==(byte/signed byte/word/signed word/dword/signed dword) 1) goto myprintf::@43
|
||||
to:myprintf::@34
|
||||
myprintf::@34: scope:[myprintf] from myprintf::@33
|
||||
[122] (word~) myprintf::w#53 ← (word) myprintf::w3#7
|
||||
to:myprintf::@29
|
||||
myprintf::@29: scope:[myprintf] from myprintf::@34 myprintf::@42 myprintf::@43
|
||||
[123] (word) myprintf::w#21 ← phi( myprintf::@42/(word~) myprintf::w#51 myprintf::@43/(word~) myprintf::w#52 myprintf::@34/(word~) myprintf::w#53 )
|
||||
[124] (byte) myprintf::bArg#1 ← ++ (byte) myprintf::bArg#12
|
||||
to:myprintf::@27
|
||||
myprintf::@43: scope:[myprintf] from myprintf::@33
|
||||
[125] (word~) myprintf::w#52 ← (word) myprintf::w2#7
|
||||
to:myprintf::@29
|
||||
myprintf::@42: scope:[myprintf] from myprintf::@32
|
||||
[126] (word~) myprintf::w#51 ← (word) myprintf::w1#6
|
||||
to:myprintf::@29
|
||||
myprintf::@28: scope:[myprintf] from myprintf::@2
|
||||
[127] if((byte) myprintf::b#1>=(byte/signed byte/word/signed word/dword/signed dword) $41) goto myprintf::@41
|
||||
to:myprintf::@30
|
||||
myprintf::@30: scope:[myprintf] from myprintf::@28 myprintf::@35 myprintf::@41
|
||||
[128] (byte) myprintf::b#25 ← phi( myprintf::@28/(byte) myprintf::b#1 myprintf::@35/(byte) myprintf::b#6 )
|
||||
[129] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#14) ← (byte) myprintf::b#25
|
||||
[130] (byte) myprintf::bLen#7 ← ++ (byte) myprintf::bLen#14
|
||||
to:myprintf::@27
|
||||
myprintf::@41: scope:[myprintf] from myprintf::@28
|
||||
[131] if((byte) myprintf::b#1<(byte/signed byte/word/signed word/dword/signed dword) $5a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto myprintf::@35
|
||||
to:myprintf::@30
|
||||
myprintf::@35: scope:[myprintf] from myprintf::@41
|
||||
[132] (byte) myprintf::b#6 ← (byte) myprintf::b#1 + (byte/signed byte/word/signed word/dword/signed dword) $20
|
||||
to:myprintf::@30
|
||||
utoa: scope:[utoa] from myprintf::@7
|
||||
[133] phi()
|
||||
to:utoa::@13
|
||||
utoa::@13: scope:[utoa] from utoa
|
||||
[134] if((word) utoa::value#4>=(word/signed word/dword/signed dword) $2710) goto utoa::@5
|
||||
to:utoa::@1
|
||||
utoa::@1: scope:[utoa] from utoa::@13 utoa::@9
|
||||
[135] (byte*) utoa::dst#16 ← phi( utoa::@13/(const byte[6]) myprintf::buf6#0 utoa::@9/++(const byte[6]) myprintf::buf6#0 )
|
||||
[135] (word) utoa::value#6 ← phi( utoa::@13/(word) utoa::value#4 utoa::@9/(word) utoa::value#0 )
|
||||
[135] (byte) utoa::bStarted#5 ← phi( utoa::@13/(byte/signed byte/word/signed word/dword/signed dword) 0 utoa::@9/(byte/signed byte/word/signed word/dword/signed dword) 1 )
|
||||
[136] if((byte) utoa::bStarted#5==(byte/signed byte/word/signed word/dword/signed dword) 1) goto utoa::@6
|
||||
to:utoa::@14
|
||||
utoa::@14: scope:[utoa] from utoa::@1
|
||||
[137] if((word) utoa::value#6>=(word/signed word/dword/signed dword) $3e8) goto utoa::@6
|
||||
to:utoa::@2
|
||||
utoa::@2: scope:[utoa] from utoa::@10 utoa::@14
|
||||
[138] (byte*) utoa::dst#10 ← phi( utoa::@14/(byte*) utoa::dst#16 utoa::@10/(byte*) utoa::dst#1 )
|
||||
[138] (word) utoa::value#11 ← phi( utoa::@14/(word) utoa::value#6 utoa::@10/(word) utoa::value#1 )
|
||||
[138] (byte) utoa::bStarted#6 ← phi( utoa::@14/(byte) utoa::bStarted#5 utoa::@10/(byte/signed byte/word/signed word/dword/signed dword) 1 )
|
||||
[139] if((byte) utoa::bStarted#6==(byte/signed byte/word/signed word/dword/signed dword) 1) goto utoa::@7
|
||||
to:utoa::@15
|
||||
utoa::@15: scope:[utoa] from utoa::@2
|
||||
[140] if((word) utoa::value#11>=(byte/signed byte/word/signed word/dword/signed dword) $64) goto utoa::@7
|
||||
to:utoa::@3
|
||||
utoa::@3: scope:[utoa] from utoa::@11 utoa::@15
|
||||
[141] (byte*) utoa::dst#13 ← phi( utoa::@11/(byte*) utoa::dst#2 utoa::@15/(byte*) utoa::dst#10 )
|
||||
[141] (word) utoa::value#10 ← phi( utoa::@11/(word) utoa::value#2 utoa::@15/(word) utoa::value#11 )
|
||||
[141] (byte) utoa::bStarted#7 ← phi( utoa::@11/(byte/signed byte/word/signed word/dword/signed dword) 1 utoa::@15/(byte) utoa::bStarted#6 )
|
||||
[142] if((byte) utoa::bStarted#7==(byte/signed byte/word/signed word/dword/signed dword) 1) goto utoa::@8
|
||||
to:utoa::@16
|
||||
utoa::@16: scope:[utoa] from utoa::@3
|
||||
[143] if((word) utoa::value#10>=(byte/signed byte/word/signed word/dword/signed dword) $a) goto utoa::@8
|
||||
to:utoa::@4
|
||||
utoa::@4: scope:[utoa] from utoa::@12 utoa::@16
|
||||
[144] (byte*) utoa::dst#12 ← phi( utoa::@12/(byte*) utoa::dst#4 utoa::@16/(byte*) utoa::dst#13 )
|
||||
[144] (word) utoa::value#12 ← phi( utoa::@12/(word) utoa::value#3 utoa::@16/(word) utoa::value#10 )
|
||||
[145] (byte~) utoa::$16 ← ((byte)) (word) utoa::value#12
|
||||
[146] (byte~) utoa::$17 ← (byte) '0' + (byte~) utoa::$16
|
||||
[147] *((byte*) utoa::dst#12) ← (byte~) utoa::$17
|
||||
[148] (byte*) utoa::dst#3 ← ++ (byte*) utoa::dst#12
|
||||
[149] *((byte*) utoa::dst#3) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:utoa::@return
|
||||
utoa::@return: scope:[utoa] from utoa::@4
|
||||
[150] return
|
||||
to:@return
|
||||
utoa::@8: scope:[utoa] from utoa::@16 utoa::@3
|
||||
[151] (byte*) append::dst#3 ← (byte*) utoa::dst#13
|
||||
[152] (word) append::value#4 ← (word) utoa::value#10
|
||||
[153] call append
|
||||
[154] (word) append::return#10 ← (word) append::value#5
|
||||
to:utoa::@12
|
||||
utoa::@12: scope:[utoa] from utoa::@8
|
||||
[155] (word) utoa::value#3 ← (word) append::return#10
|
||||
[156] (byte*) utoa::dst#4 ← ++ (byte*) utoa::dst#13
|
||||
to:utoa::@4
|
||||
utoa::@7: scope:[utoa] from utoa::@15 utoa::@2
|
||||
[157] (byte*) append::dst#2 ← (byte*) utoa::dst#10
|
||||
[158] (word) append::value#3 ← (word) utoa::value#11
|
||||
[159] call append
|
||||
[160] (word) append::return#4 ← (word) append::value#5
|
||||
to:utoa::@11
|
||||
utoa::@11: scope:[utoa] from utoa::@7
|
||||
[161] (word) utoa::value#2 ← (word) append::return#4
|
||||
[162] (byte*) utoa::dst#2 ← ++ (byte*) utoa::dst#10
|
||||
to:utoa::@3
|
||||
utoa::@6: scope:[utoa] from utoa::@1 utoa::@14
|
||||
[163] (byte*) append::dst#1 ← (byte*) utoa::dst#16
|
||||
[164] (word) append::value#2 ← (word) utoa::value#6
|
||||
[165] call append
|
||||
[166] (word) append::return#3 ← (word) append::value#5
|
||||
to:utoa::@10
|
||||
utoa::@10: scope:[utoa] from utoa::@6
|
||||
[167] (word) utoa::value#1 ← (word) append::return#3
|
||||
[168] (byte*) utoa::dst#1 ← ++ (byte*) utoa::dst#16
|
||||
to:utoa::@2
|
||||
utoa::@5: scope:[utoa] from utoa::@13
|
||||
[169] (word) append::value#1 ← (word) utoa::value#4
|
||||
[170] call append
|
||||
[171] (word) append::return#2 ← (word) append::value#5
|
||||
to:utoa::@9
|
||||
utoa::@9: scope:[utoa] from utoa::@5
|
||||
[172] (word) utoa::value#0 ← (word) append::return#2
|
||||
to:utoa::@1
|
||||
append: scope:[append] from utoa::@5 utoa::@6 utoa::@7 utoa::@8
|
||||
[173] (word) append::sub#6 ← phi( utoa::@5/(word/signed word/dword/signed dword) $2710 utoa::@6/(word/signed word/dword/signed dword) $3e8 utoa::@7/(byte/signed byte/word/signed word/dword/signed dword) $64 utoa::@8/(byte/signed byte/word/signed word/dword/signed dword) $a )
|
||||
[173] (word) append::value#8 ← phi( utoa::@5/(word) append::value#1 utoa::@6/(word) append::value#2 utoa::@7/(word) append::value#3 utoa::@8/(word) append::value#4 )
|
||||
[173] (byte*) append::dst#4 ← phi( utoa::@5/(const byte[6]) myprintf::buf6#0 utoa::@6/(byte*) append::dst#1 utoa::@7/(byte*) append::dst#2 utoa::@8/(byte*) append::dst#3 )
|
||||
[174] *((byte*) append::dst#4) ← (byte) '0'
|
||||
to:append::@1
|
||||
append::@1: scope:[append] from append append::@2
|
||||
[175] (word) append::value#5 ← phi( append/(word) append::value#8 append::@2/(word) append::value#0 )
|
||||
[176] if((word) append::value#5>=(word) append::sub#6) goto append::@2
|
||||
to:append::@return
|
||||
append::@return: scope:[append] from append::@1
|
||||
[177] return
|
||||
to:@return
|
||||
append::@2: scope:[append] from append::@1
|
||||
[178] *((byte*) append::dst#4) ← ++ *((byte*) append::dst#4)
|
||||
[179] (word) append::value#0 ← (word) append::value#5 - (word) append::sub#6
|
||||
to:append::@1
|
||||
div10: scope:[div10] from main::@6
|
||||
[180] (word~) div10::$0 ← (word) div10::val#4 >> (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[181] (word) div10::val#0 ← (word~) div10::$0 + (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[182] (word~) div10::$2 ← (word) div10::val#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[183] (word) div10::val#1 ← (word) div10::val#0 + (word~) div10::$2
|
||||
[184] (word~) div10::$3 ← (word) div10::val#1 >> (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
[185] (word) div10::val#2 ← (word) div10::val#1 + (word~) div10::$3
|
||||
[186] (word~) div10::$4 ← (word) div10::val#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
[187] (word~) div10::$5 ← (word~) div10::$4 >> (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
[188] (word) div10::val#3 ← (word) div10::val#2 + (word~) div10::$5
|
||||
[189] (word) div10::return#0 ← (word) div10::val#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4
|
||||
to:div10::@return
|
||||
div10::@return: scope:[div10] from div10
|
||||
[190] return
|
||||
to:@return
|
||||
div16u: scope:[div16u] from main::@2
|
||||
[191] (word) divr16u::dividend#1 ← (word) div16u::dividend#0
|
||||
[192] call divr16u
|
||||
[193] (word) divr16u::return#2 ← (word) divr16u::return#0
|
||||
to:div16u::@1
|
||||
div16u::@1: scope:[div16u] from div16u
|
||||
[194] (word) div16u::return#0 ← (word) divr16u::return#2
|
||||
to:div16u::@return
|
||||
div16u::@return: scope:[div16u] from div16u::@1
|
||||
[195] return
|
||||
to:@return
|
||||
divr16u: scope:[divr16u] from div16u
|
||||
[196] phi()
|
||||
to:divr16u::@1
|
||||
divr16u::@1: scope:[divr16u] from divr16u divr16u::@3
|
||||
[197] (byte) divr16u::i#2 ← phi( divr16u/(byte/signed byte/word/signed word/dword/signed dword) 0 divr16u::@3/(byte) divr16u::i#1 )
|
||||
[197] (word) divr16u::quotient#3 ← phi( divr16u/(byte/signed byte/word/signed word/dword/signed dword) 0 divr16u::@3/(word) divr16u::return#0 )
|
||||
[197] (word) divr16u::dividend#2 ← phi( divr16u/(word) divr16u::dividend#1 divr16u::@3/(word) divr16u::dividend#0 )
|
||||
[197] (word) divr16u::rem#4 ← phi( divr16u/(byte/signed byte/word/signed word/dword/signed dword) 0 divr16u::@3/(word) divr16u::rem#9 )
|
||||
[198] (word) divr16u::rem#0 ← (word) divr16u::rem#4 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[199] (byte~) divr16u::$1 ← > (word) divr16u::dividend#2
|
||||
[200] (byte~) divr16u::$2 ← (byte~) divr16u::$1 & (byte/word/signed word/dword/signed dword) $80
|
||||
[201] if((byte~) divr16u::$2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto divr16u::@2
|
||||
to:divr16u::@4
|
||||
divr16u::@4: scope:[divr16u] from divr16u::@1
|
||||
[202] (word) divr16u::rem#1 ← (word) divr16u::rem#0 | (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
to:divr16u::@2
|
||||
divr16u::@2: scope:[divr16u] from divr16u::@1 divr16u::@4
|
||||
[203] (word) divr16u::rem#5 ← phi( divr16u::@1/(word) divr16u::rem#0 divr16u::@4/(word) divr16u::rem#1 )
|
||||
[204] (word) divr16u::dividend#0 ← (word) divr16u::dividend#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[205] (word) divr16u::quotient#1 ← (word) divr16u::quotient#3 << (byte/signed byte/word/signed word/dword/signed dword) 1
|
||||
[206] if((word) divr16u::rem#5<(const word) div16u::divisor#0) goto divr16u::@3
|
||||
to:divr16u::@5
|
||||
divr16u::@5: scope:[divr16u] from divr16u::@2
|
||||
[207] (word) divr16u::quotient#2 ← ++ (word) divr16u::quotient#1
|
||||
[208] (word) divr16u::rem#2 ← (word) divr16u::rem#5 - (const word) div16u::divisor#0
|
||||
to:divr16u::@3
|
||||
divr16u::@3: scope:[divr16u] from divr16u::@2 divr16u::@5
|
||||
[209] (word) divr16u::return#0 ← phi( divr16u::@2/(word) divr16u::quotient#1 divr16u::@5/(word) divr16u::quotient#2 )
|
||||
[209] (word) divr16u::rem#9 ← phi( divr16u::@2/(word) divr16u::rem#5 divr16u::@5/(word) divr16u::rem#2 )
|
||||
[210] (byte) divr16u::i#1 ← ++ (byte) divr16u::i#2
|
||||
[211] if((byte) divr16u::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $10) goto divr16u::@1
|
||||
to:divr16u::@return
|
||||
divr16u::@return: scope:[divr16u] from divr16u::@3
|
||||
[212] return
|
||||
to:@return
|
9025
src/test/ref/sandbox.log
Normal file
9025
src/test/ref/sandbox.log
Normal file
File diff suppressed because it is too large
Load Diff
333
src/test/ref/sandbox.sym
Normal file
333
src/test/ref/sandbox.sym
Normal file
@ -0,0 +1,333 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) Print()
|
||||
(label) Print::@return
|
||||
(byte*) TIMEHI
|
||||
(const byte*) TIMEHI#0 TIMEHI = ((byte*))(byte/word/signed word/dword/signed dword) $a1
|
||||
(byte*) TIMELO
|
||||
(const byte*) TIMELO#0 TIMELO = ((byte*))(byte/word/signed word/dword/signed dword) $a2
|
||||
(byte*) VICBANK
|
||||
(const byte*) VICBANK#0 VICBANK = ((byte*))(word/dword/signed dword) $d018
|
||||
(word()) append((byte*) append::dst , (word) append::value , (word) append::sub)
|
||||
(label) append::@1
|
||||
(label) append::@2
|
||||
(label) append::@return
|
||||
(byte*) append::dst
|
||||
(byte*) append::dst#1 dst zp ZP_WORD:20 2.0
|
||||
(byte*) append::dst#2 dst zp ZP_WORD:20 2.0
|
||||
(byte*) append::dst#3 dst zp ZP_WORD:20 2.0
|
||||
(byte*) append::dst#4 dst zp ZP_WORD:20 335.0
|
||||
(word) append::return
|
||||
(word) append::return#10 return zp ZP_WORD:18 4.0
|
||||
(word) append::return#2 return zp ZP_WORD:18 4.0
|
||||
(word) append::return#3 return zp ZP_WORD:18 4.0
|
||||
(word) append::return#4 return zp ZP_WORD:18 4.0
|
||||
(word) append::sub
|
||||
(word) append::sub#6 sub zp ZP_WORD:22 333.6666666666667
|
||||
(word) append::value
|
||||
(word) append::value#0 value zp ZP_WORD:18 2002.0
|
||||
(word) append::value#1 value zp ZP_WORD:18 4.0
|
||||
(word) append::value#2 value zp ZP_WORD:18 4.0
|
||||
(word) append::value#3 value zp ZP_WORD:18 4.0
|
||||
(word) append::value#4 value zp ZP_WORD:18 4.0
|
||||
(word) append::value#5 value zp ZP_WORD:18 376.625
|
||||
(word) append::value#8 value zp ZP_WORD:18 5.0
|
||||
(word()) div10((word) div10::val)
|
||||
(word~) div10::$0 $0 zp ZP_WORD:4 4.0
|
||||
(word~) div10::$2 $2 zp ZP_WORD:6 4.0
|
||||
(word~) div10::$3 $3 zp ZP_WORD:4 4.0
|
||||
(word~) div10::$4 $4 zp ZP_WORD:6 4.0
|
||||
(word~) div10::$5 $5 zp ZP_WORD:6 4.0
|
||||
(label) div10::@return
|
||||
(word) div10::return
|
||||
(word) div10::return#0 return zp ZP_WORD:4 34.33333333333333
|
||||
(word) div10::return#2 return zp ZP_WORD:4 202.0
|
||||
(word) div10::val
|
||||
(word) div10::val#0 val zp ZP_WORD:4 3.0
|
||||
(word) div10::val#1 val#1 zp ZP_WORD:6 3.0
|
||||
(word) div10::val#2 val zp ZP_WORD:4 2.0
|
||||
(word) div10::val#3 val zp ZP_WORD:4 4.0
|
||||
(word) div10::val#4 val#4 zp ZP_WORD:2 103.0
|
||||
(word()) div16u((word) div16u::dividend , (word) div16u::divisor)
|
||||
(label) div16u::@1
|
||||
(label) div16u::@return
|
||||
(word) div16u::dividend
|
||||
(word) div16u::dividend#0 dividend zp ZP_WORD:2 103.0
|
||||
(word) div16u::divisor
|
||||
(const word) div16u::divisor#0 divisor = (byte/signed byte/word/signed word/dword/signed dword) $a
|
||||
(word) div16u::return
|
||||
(word) div16u::return#0 return zp ZP_WORD:4 34.33333333333333
|
||||
(word) div16u::return#2 return zp ZP_WORD:4 202.0
|
||||
(word()) divr16u((word) divr16u::dividend , (word) divr16u::divisor , (word) divr16u::rem)
|
||||
(byte~) divr16u::$1 reg byte a 2002.0
|
||||
(byte~) divr16u::$2 reg byte a 2002.0
|
||||
(label) divr16u::@1
|
||||
(label) divr16u::@2
|
||||
(label) divr16u::@3
|
||||
(label) divr16u::@4
|
||||
(label) divr16u::@5
|
||||
(label) divr16u::@return
|
||||
(word) divr16u::dividend
|
||||
(word) divr16u::dividend#0 dividend zp ZP_WORD:8 250.25
|
||||
(word) divr16u::dividend#1 dividend zp ZP_WORD:8 2.0
|
||||
(word) divr16u::dividend#2 dividend zp ZP_WORD:8 429.2857142857143
|
||||
(word) divr16u::divisor
|
||||
(byte) divr16u::i
|
||||
(byte) divr16u::i#1 reg byte x 1501.5
|
||||
(byte) divr16u::i#2 reg byte x 154.0
|
||||
(word) divr16u::quotient
|
||||
(word) divr16u::quotient#1 quotient zp ZP_WORD:4 1501.5
|
||||
(word) divr16u::quotient#2 quotient zp ZP_WORD:4 1001.0
|
||||
(word) divr16u::quotient#3 quotient zp ZP_WORD:4 250.25
|
||||
(word) divr16u::rem
|
||||
(word) divr16u::rem#0 rem zp ZP_WORD:6 750.75
|
||||
(word) divr16u::rem#1 rem zp ZP_WORD:6 2002.0
|
||||
(word) divr16u::rem#2 rem zp ZP_WORD:6 2002.0
|
||||
(word) divr16u::rem#4 rem zp ZP_WORD:6 2002.0
|
||||
(word) divr16u::rem#5 rem zp ZP_WORD:6 1001.0
|
||||
(word) divr16u::rem#9 rem zp ZP_WORD:6 1001.0
|
||||
(word) divr16u::return
|
||||
(word) divr16u::return#0 return zp ZP_WORD:4 601.0
|
||||
(word) divr16u::return#2 return zp ZP_WORD:4 4.0
|
||||
(signed word()) main()
|
||||
(word~) main::$11 $11 zp ZP_WORD:6 22.0
|
||||
(word~) main::$12 $12 zp ZP_WORD:6 11.0
|
||||
(word~) main::$13 $13 zp ZP_WORD:8 22.0
|
||||
(word~) main::$2 $2 zp ZP_WORD:6 22.0
|
||||
(word~) main::$3 $3 zp ZP_WORD:6 11.0
|
||||
(word~) main::$4 $4 zp ZP_WORD:8 22.0
|
||||
(label) main::@1
|
||||
(label) main::@10
|
||||
(label) main::@11
|
||||
(label) main::@12
|
||||
(label) main::@13
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@9
|
||||
(label) main::@return
|
||||
(signed word) main::return
|
||||
(const string) main::str str = (string) "200 DIV16U: %5d,%4d IN %04d FRAMESm@"
|
||||
(const string) main::str1 str1 = (string) "200 DIV10 : %5d,%4d IN %04d FRAMESm@"
|
||||
(word) main::u
|
||||
(word) main::u#11 u zp ZP_WORD:2 7.05263157894737
|
||||
(word) main::u#15 u zp ZP_WORD:2 7.05263157894737
|
||||
(word) main::u#2 u zp ZP_WORD:2 7.333333333333333
|
||||
(word) main::u#4 u zp ZP_WORD:2 7.333333333333333
|
||||
(word) main::v
|
||||
(word) main::v#1 v zp ZP_WORD:4 14.0
|
||||
(word) main::v#2 v zp ZP_WORD:4 14.0
|
||||
(byte()) myprintf((byte*) myprintf::dst , (byte*) myprintf::str , (word) myprintf::w1 , (word) myprintf::w2 , (word) myprintf::w3)
|
||||
(word~) myprintf::$17 $17 zp ZP_WORD:18 202.0
|
||||
(byte~) myprintf::$22 reg byte a 101.0
|
||||
(byte~) myprintf::$23 reg byte a 202.0
|
||||
(byte~) myprintf::$28 reg byte a 101.0
|
||||
(byte~) myprintf::$29 reg byte a 202.0
|
||||
(byte~) myprintf::$39 reg byte a 1001.0
|
||||
(byte~) myprintf::$47 reg byte a 202.0
|
||||
(label) myprintf::@1
|
||||
(label) myprintf::@10
|
||||
(label) myprintf::@11
|
||||
(label) myprintf::@12
|
||||
(label) myprintf::@13
|
||||
(label) myprintf::@14
|
||||
(label) myprintf::@15
|
||||
(label) myprintf::@16
|
||||
(label) myprintf::@17
|
||||
(label) myprintf::@18
|
||||
(label) myprintf::@19
|
||||
(label) myprintf::@2
|
||||
(label) myprintf::@20
|
||||
(label) myprintf::@21
|
||||
(label) myprintf::@22
|
||||
(label) myprintf::@23
|
||||
(label) myprintf::@24
|
||||
(label) myprintf::@25
|
||||
(label) myprintf::@26
|
||||
(label) myprintf::@27
|
||||
(label) myprintf::@28
|
||||
(label) myprintf::@29
|
||||
(label) myprintf::@3
|
||||
(label) myprintf::@30
|
||||
(label) myprintf::@31
|
||||
(label) myprintf::@32
|
||||
(label) myprintf::@33
|
||||
(label) myprintf::@34
|
||||
(label) myprintf::@35
|
||||
(label) myprintf::@36
|
||||
(label) myprintf::@37
|
||||
(label) myprintf::@38
|
||||
(label) myprintf::@39
|
||||
(label) myprintf::@4
|
||||
(label) myprintf::@40
|
||||
(label) myprintf::@41
|
||||
(label) myprintf::@42
|
||||
(label) myprintf::@43
|
||||
(label) myprintf::@5
|
||||
(label) myprintf::@6
|
||||
(label) myprintf::@7
|
||||
(label) myprintf::@8
|
||||
(label) myprintf::@9
|
||||
(label) myprintf::@return
|
||||
(byte) myprintf::b
|
||||
(byte) myprintf::b#1 reg byte x 126.25000000000003
|
||||
(byte) myprintf::b#15 reg byte x 75.75
|
||||
(byte) myprintf::b#16 reg byte x 75.75
|
||||
(byte) myprintf::b#17 reg byte x 248.32
|
||||
(byte) myprintf::b#25 reg byte x 303.0
|
||||
(byte) myprintf::b#5 reg byte x 2002.0
|
||||
(byte) myprintf::b#6 reg byte x 202.0
|
||||
(byte) myprintf::bArg
|
||||
(byte) myprintf::bArg#1 bArg zp ZP_BYTE:11 202.0
|
||||
(byte) myprintf::bArg#10 bArg zp ZP_BYTE:11 235.66666666666663
|
||||
(byte) myprintf::bArg#12 bArg zp ZP_BYTE:11 12.625
|
||||
(byte) myprintf::bDigits
|
||||
(byte) myprintf::bDigits#1 bDigits zp ZP_BYTE:17 202.0
|
||||
(byte) myprintf::bDigits#10 bDigits zp ZP_BYTE:17 350.5
|
||||
(byte) myprintf::bDigits#14 bDigits zp ZP_BYTE:17 23.488372093023255
|
||||
(byte) myprintf::bDigits#16 bDigits zp ZP_BYTE:17 188.25
|
||||
(byte) myprintf::bDigits#2 bDigits zp ZP_BYTE:17 2002.0
|
||||
(byte) myprintf::bDigits#24 bDigits zp ZP_BYTE:17 201.99999999999997
|
||||
(byte) myprintf::bDigits#25 bDigits zp ZP_BYTE:17 1607.0
|
||||
(byte) myprintf::bDigits#3 bDigits zp ZP_BYTE:17 2002.0
|
||||
(byte) myprintf::bDigits#8 bDigits zp ZP_BYTE:17 701.0
|
||||
(byte) myprintf::bFormat
|
||||
(byte) myprintf::bFormat#10 bFormat zp ZP_BYTE:10 40.4
|
||||
(byte) myprintf::bFormat#4 bFormat zp ZP_BYTE:10 168.33333333333331
|
||||
(byte) myprintf::bLeadZero
|
||||
(byte) myprintf::bLeadZero#10 bLeadZero zp ZP_BYTE:15 22.818181818181817
|
||||
(byte) myprintf::bLeadZero#18 bLeadZero zp ZP_BYTE:15 168.33333333333331
|
||||
(byte) myprintf::bLen
|
||||
(byte) myprintf::bLen#1 bLen zp ZP_BYTE:16 202.0
|
||||
(byte) myprintf::bLen#10 reg byte y 43.285714285714285
|
||||
(byte) myprintf::bLen#11 bLen zp ZP_BYTE:16 620.8
|
||||
(byte) myprintf::bLen#12 bLen zp ZP_BYTE:16 1552.0
|
||||
(byte) myprintf::bLen#13 bLen zp ZP_BYTE:16 1552.0
|
||||
(byte) myprintf::bLen#14 bLen zp ZP_BYTE:16 34.487804878048784
|
||||
(byte) myprintf::bLen#23 bLen zp ZP_BYTE:16 1203.0
|
||||
(byte) myprintf::bLen#24 bLen zp ZP_BYTE:16 460.99999999999994
|
||||
(byte) myprintf::bLen#28 bLen zp ZP_BYTE:16 1607.0
|
||||
(byte) myprintf::bLen#3 bLen zp ZP_BYTE:16 202.0
|
||||
(byte) myprintf::bLen#4 bLen zp ZP_BYTE:16 1001.0
|
||||
(byte) myprintf::bLen#6 bLen zp ZP_BYTE:16 1001.0
|
||||
(byte) myprintf::bLen#7 bLen zp ZP_BYTE:16 202.0
|
||||
(byte) myprintf::bTrailing
|
||||
(byte) myprintf::bTrailing#10 bTrailing zp ZP_BYTE:14 10.712121212121211
|
||||
(byte) myprintf::bTrailing#21 bTrailing zp ZP_BYTE:14 168.33333333333331
|
||||
(byte[6]) myprintf::buf6
|
||||
(const byte[6]) myprintf::buf6#0 buf6 = { fill( 6, 0) }
|
||||
(byte) myprintf::digit
|
||||
(byte) myprintf::digit#2 digit zp ZP_BYTE:10 1501.5
|
||||
(byte) myprintf::digit#3 digit zp ZP_BYTE:10 1001.0
|
||||
(byte*) myprintf::dst
|
||||
(byte) myprintf::return
|
||||
(byte) myprintf::return#0 return zp ZP_BYTE:16 236.3333333333333
|
||||
(byte*) myprintf::str
|
||||
(byte*) myprintf::str#0 str zp ZP_WORD:8 151.5
|
||||
(byte*) myprintf::str#10 str zp ZP_WORD:8 4.121621621621622
|
||||
(byte*) myprintf::str#5 str zp ZP_WORD:8 2.0
|
||||
(word) myprintf::w
|
||||
(word) myprintf::w#10 w zp ZP_WORD:12 15.303030303030305
|
||||
(word) myprintf::w#17 w zp ZP_WORD:12 235.66666666666663
|
||||
(word) myprintf::w#21 w zp ZP_WORD:12 202.0
|
||||
(word~) myprintf::w#51 w zp ZP_WORD:12 202.0
|
||||
(word~) myprintf::w#52 w zp ZP_WORD:12 202.0
|
||||
(word~) myprintf::w#53 w zp ZP_WORD:12 202.0
|
||||
(word) myprintf::w1
|
||||
(word) myprintf::w1#0 w1 zp ZP_WORD:2 11.0
|
||||
(word) myprintf::w1#1 w1 zp ZP_WORD:2 11.0
|
||||
(word) myprintf::w1#6 w1 zp ZP_WORD:2 1.5974025974025974
|
||||
(word) myprintf::w2
|
||||
(word) myprintf::w2#0 w2 zp ZP_WORD:4 22.0
|
||||
(word) myprintf::w2#1 w2 zp ZP_WORD:4 22.0
|
||||
(word) myprintf::w2#7 w2 zp ZP_WORD:4 1.5974025974025974
|
||||
(word) myprintf::w3
|
||||
(word) myprintf::w3#0 w3 zp ZP_WORD:6 7.333333333333333
|
||||
(word) myprintf::w3#1 w3 zp ZP_WORD:6 7.333333333333333
|
||||
(word) myprintf::w3#7 w3 zp ZP_WORD:6 1.5974025974025974
|
||||
(byte[$64]) strTemp
|
||||
(const byte[$64]) strTemp#0 strTemp = { fill( $64, 0) }
|
||||
(void()) utoa((word) utoa::value , (byte*) utoa::dst)
|
||||
(byte~) utoa::$16 reg byte a 4.0
|
||||
(byte~) utoa::$17 reg byte a 4.0
|
||||
(label) utoa::@1
|
||||
(label) utoa::@10
|
||||
(label) utoa::@11
|
||||
(label) utoa::@12
|
||||
(label) utoa::@13
|
||||
(label) utoa::@14
|
||||
(label) utoa::@15
|
||||
(label) utoa::@16
|
||||
(label) utoa::@2
|
||||
(label) utoa::@3
|
||||
(label) utoa::@4
|
||||
(label) utoa::@5
|
||||
(label) utoa::@6
|
||||
(label) utoa::@7
|
||||
(label) utoa::@8
|
||||
(label) utoa::@9
|
||||
(label) utoa::@return
|
||||
(byte) utoa::bStarted
|
||||
(byte) utoa::bStarted#5 reg byte x 1.3333333333333333
|
||||
(byte) utoa::bStarted#6 reg byte x 2.0
|
||||
(byte) utoa::bStarted#7 reg byte x 4.0
|
||||
(byte*) utoa::dst
|
||||
(byte*) utoa::dst#1 dst zp ZP_WORD:20 4.0
|
||||
(byte*) utoa::dst#10 dst zp ZP_WORD:20 1.25
|
||||
(byte*) utoa::dst#12 dst zp ZP_WORD:20 2.0
|
||||
(byte*) utoa::dst#13 dst zp ZP_WORD:20 1.25
|
||||
(byte*) utoa::dst#16 dst zp ZP_WORD:20 0.75
|
||||
(byte*) utoa::dst#2 dst zp ZP_WORD:20 4.0
|
||||
(byte*) utoa::dst#3 dst zp ZP_WORD:20 4.0
|
||||
(byte*) utoa::dst#4 dst zp ZP_WORD:20 4.0
|
||||
(word) utoa::value
|
||||
(word) utoa::value#0 value zp ZP_WORD:18 4.0
|
||||
(word) utoa::value#1 value zp ZP_WORD:18 2.0
|
||||
(word) utoa::value#10 value zp ZP_WORD:18 2.5
|
||||
(word) utoa::value#11 value zp ZP_WORD:18 2.5
|
||||
(word) utoa::value#12 value zp ZP_WORD:18 6.0
|
||||
(word) utoa::value#2 value zp ZP_WORD:18 2.0
|
||||
(word) utoa::value#3 value zp ZP_WORD:18 2.0
|
||||
(word) utoa::value#4 value zp ZP_WORD:18 35.66666666666666
|
||||
(word) utoa::value#6 value zp ZP_WORD:18 2.5
|
||||
(byte*) zp1
|
||||
(const byte*) zp1#0 zp1 = ((byte*))(byte/signed byte/word/signed word/dword/signed dword) $61
|
||||
(byte*) zp2
|
||||
(const byte*) zp2#0 zp2 = ((byte*))(byte/signed byte/word/signed word/dword/signed dword) $62
|
||||
|
||||
zp ZP_WORD:2 [ main::u#11 main::u#2 myprintf::w1#6 myprintf::w1#0 myprintf::w1#1 div16u::dividend#0 main::u#15 main::u#4 div10::val#4 ]
|
||||
zp ZP_WORD:4 [ myprintf::w2#7 myprintf::w2#0 myprintf::w2#1 main::v#1 main::v#2 div16u::return#2 div16u::return#0 div10::return#2 div10::return#0 divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 div10::$3 div10::val#2 div10::val#3 div10::$0 div10::val#0 ]
|
||||
zp ZP_WORD:6 [ myprintf::w3#7 myprintf::w3#0 myprintf::w3#1 main::$3 main::$12 main::$2 main::$11 divr16u::rem#4 divr16u::rem#9 divr16u::rem#5 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 div10::$2 div10::val#1 div10::$4 div10::$5 ]
|
||||
zp ZP_WORD:8 [ myprintf::str#10 myprintf::str#5 myprintf::str#0 divr16u::dividend#2 divr16u::dividend#1 divr16u::dividend#0 main::$4 main::$13 ]
|
||||
zp ZP_BYTE:10 [ myprintf::bFormat#10 myprintf::bFormat#4 myprintf::digit#3 myprintf::digit#2 ]
|
||||
zp ZP_BYTE:11 [ myprintf::bArg#12 myprintf::bArg#10 myprintf::bArg#1 ]
|
||||
zp ZP_WORD:12 [ myprintf::w#10 myprintf::w#17 myprintf::w#21 myprintf::w#51 myprintf::w#52 myprintf::w#53 ]
|
||||
zp ZP_BYTE:14 [ myprintf::bTrailing#10 myprintf::bTrailing#21 ]
|
||||
zp ZP_BYTE:15 [ myprintf::bLeadZero#10 myprintf::bLeadZero#18 ]
|
||||
reg byte a [ myprintf::$22 ]
|
||||
reg byte a [ myprintf::$28 ]
|
||||
reg byte x [ myprintf::b#17 myprintf::b#5 ]
|
||||
zp ZP_BYTE:16 [ myprintf::bLen#11 myprintf::bLen#13 myprintf::bLen#12 myprintf::bLen#23 myprintf::bLen#14 myprintf::return#0 myprintf::bLen#28 myprintf::bLen#7 myprintf::bLen#3 myprintf::bLen#24 myprintf::bLen#6 myprintf::bLen#1 myprintf::bLen#4 ]
|
||||
zp ZP_BYTE:17 [ myprintf::bDigits#10 myprintf::bDigits#8 myprintf::bDigits#14 myprintf::bDigits#24 myprintf::bDigits#25 myprintf::bDigits#1 myprintf::bDigits#16 myprintf::bDigits#3 myprintf::bDigits#2 ]
|
||||
reg byte a [ myprintf::$39 ]
|
||||
reg byte x [ myprintf::b#25 myprintf::b#1 myprintf::b#6 ]
|
||||
reg byte x [ utoa::bStarted#7 utoa::bStarted#6 utoa::bStarted#5 ]
|
||||
zp ZP_WORD:18 [ utoa::value#12 utoa::value#3 utoa::value#10 utoa::value#2 utoa::value#11 utoa::value#6 utoa::value#4 utoa::value#0 utoa::value#1 append::value#5 append::value#8 append::value#1 append::value#2 append::value#3 append::value#4 append::value#0 append::return#10 append::return#4 append::return#3 append::return#2 myprintf::$17 ]
|
||||
zp ZP_WORD:20 [ utoa::dst#12 utoa::dst#4 utoa::dst#13 utoa::dst#2 utoa::dst#10 utoa::dst#16 utoa::dst#1 append::dst#4 append::dst#1 append::dst#2 append::dst#3 utoa::dst#3 ]
|
||||
zp ZP_WORD:22 [ append::sub#6 ]
|
||||
reg byte x [ divr16u::i#2 divr16u::i#1 ]
|
||||
reg byte x [ myprintf::b#15 ]
|
||||
reg byte a [ myprintf::$23 ]
|
||||
reg byte y [ myprintf::bLen#10 ]
|
||||
reg byte x [ myprintf::b#16 ]
|
||||
reg byte a [ myprintf::$29 ]
|
||||
reg byte a [ myprintf::$47 ]
|
||||
reg byte a [ utoa::$16 ]
|
||||
reg byte a [ utoa::$17 ]
|
||||
reg byte a [ divr16u::$1 ]
|
||||
reg byte a [ divr16u::$2 ]
|
17
src/test/ref/simple-loop.asm
Normal file
17
src/test/ref/simple-loop.asm
Normal file
@ -0,0 +1,17 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
ldx #0
|
||||
b1:
|
||||
lda #'a'
|
||||
sta SCREEN,x
|
||||
lda #0
|
||||
sta $d020
|
||||
inx
|
||||
inx
|
||||
cpx #$80
|
||||
bcc b1
|
||||
rts
|
||||
}
|
22
src/test/ref/simple-loop.cfg
Normal file
22
src/test/ref/simple-loop.cfg
Normal file
@ -0,0 +1,22 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 )
|
||||
[6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a'
|
||||
[7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
[9] if((byte) main::i#1<(byte/word/signed word/dword/signed dword) $80) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[10] return
|
||||
to:@return
|
328
src/test/ref/simple-loop.log
Normal file
328
src/test/ref/simple-loop.log
Normal file
@ -0,0 +1,328 @@
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
|
||||
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
*((byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a'
|
||||
(byte*~) main::$0 ← ((byte*)) (word/dword/signed dword) $d020
|
||||
*((byte*~) main::$0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
(byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
(bool~) main::$1 ← (byte) main::i#1 < (byte/word/signed word/dword/signed dword) $80
|
||||
if((bool~) main::$1) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
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
|
||||
(void()) main()
|
||||
(byte*~) main::$0
|
||||
(bool~) main::$1
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte*) main::SCREEN#0
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
|
||||
Culled Empty Block (label) @2
|
||||
Successful SSA optimization Pass2CullEmptyBlocks
|
||||
Simple Condition (bool~) main::$1 [8] if((byte) main::i#1<(byte/word/signed word/dword/signed dword) $80) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Constant (const byte*) main::$0 = ((byte*))$d020
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
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
|
||||
Constant inlined main::$0 = ((byte*))(word/dword/signed dword) $d020
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [11] main::i#3 ← main::i#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Culled Empty Block (label) main::@3
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 )
|
||||
[6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a'
|
||||
[7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
[8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
|
||||
[9] if((byte) main::i#1<(byte/word/signed word/dword/signed dword) $80) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[10] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 11.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
.label i = 2
|
||||
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG12 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
jmp b1
|
||||
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'a'
|
||||
ldy i
|
||||
sta SCREEN,y
|
||||
//SEG17 [7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
|
||||
lda #0
|
||||
sta $d020
|
||||
//SEG18 [8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz1_plus_2
|
||||
lda i
|
||||
clc
|
||||
adc #2
|
||||
sta i
|
||||
//SEG19 [9] if((byte) main::i#1<(byte/word/signed word/dword/signed dword) $80) goto main::@1 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda i
|
||||
cmp #$80
|
||||
bcc b1_from_b1
|
||||
jmp breturn
|
||||
//SEG20 main::@return
|
||||
breturn:
|
||||
//SEG21 [10] return
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a' [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Statement [7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
|
||||
Statement [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a' [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
|
||||
Statement [7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 343 combination reg byte x [ main::i#2 main::i#1 ]
|
||||
Uplifting [] best 343 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG9 @end
|
||||
bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG12 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp b1
|
||||
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a' -- pbuc1_derefidx_vbuxx=vbuc2
|
||||
lda #'a'
|
||||
sta SCREEN,x
|
||||
//SEG17 [7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
|
||||
lda #0
|
||||
sta $d020
|
||||
//SEG18 [8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuxx=vbuxx_plus_2
|
||||
inx
|
||||
inx
|
||||
//SEG19 [9] if((byte) main::i#1<(byte/word/signed word/dword/signed dword) $80) goto main::@1 -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$80
|
||||
bcc b1_from_b1
|
||||
jmp breturn
|
||||
//SEG20 main::@return
|
||||
breturn:
|
||||
//SEG21 [10] return
|
||||
rts
|
||||
}
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label b1_from_b1 with b1
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Removing instruction b1_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction b1_from_main:
|
||||
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
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(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 11.0
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 241
|
||||
|
||||
//SEG0 File Comments
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
//SEG3 @begin
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call main
|
||||
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG9 @end
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
//SEG12 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
//SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
//SEG15 main::@1
|
||||
b1:
|
||||
//SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) 'a' -- pbuc1_derefidx_vbuxx=vbuc2
|
||||
lda #'a'
|
||||
sta SCREEN,x
|
||||
//SEG17 [7] *(((byte*))(word/dword/signed dword) $d020) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
|
||||
lda #0
|
||||
sta $d020
|
||||
//SEG18 [8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuxx=vbuxx_plus_2
|
||||
inx
|
||||
inx
|
||||
//SEG19 [9] if((byte) main::i#1<(byte/word/signed word/dword/signed dword) $80) goto main::@1 -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$80
|
||||
bcc b1
|
||||
//SEG20 main::@return
|
||||
//SEG21 [10] return
|
||||
rts
|
||||
}
|
||||
|
13
src/test/ref/simple-loop.sym
Normal file
13
src/test/ref/simple-loop.sym
Normal file
@ -0,0 +1,13 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(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 11.0
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
Loading…
Reference in New Issue
Block a user