1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-07 06:37:31 +00:00

Removed support for LValue unary operator low/high <x >x. Added support for LValue BYTE0(), BYTE1(), ..., WORD0(), .... Closes #667

This commit is contained in:
jespergravgaard 2021-06-11 21:41:01 +02:00
parent d6d1250f51
commit ff812d6f60
60 changed files with 2561 additions and 1154 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//KICKC FRAGMENT CACHE ee20482c1 ee204a320
//FRAGMENT vbuzz=vbuc1
ldz #{c1}
//FRAGMENT vbuzz_lt_vbuc1_then_la1

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//KICKC FRAGMENT CACHE ee20482c1 ee204a320
//FRAGMENT _deref_pbuc1=vbuc2
lda #{c2}
sta {c1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//KICKC FRAGMENT CACHE ee20482c1 ee204a320
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//KICKC FRAGMENT CACHE ee20482c1 ee204a320
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}
@ -9917,7 +9917,7 @@ sta {z1}
lda {z2}+1
adc #>{c1}
sta {z1}+1
//FRAGMENT vduz1=vduz2_sethi_vwuz3
//FRAGMENT vduz1=vduz2_setword1_vwuz3
lda {z2}
sta {z1}
lda {z2}+1
@ -9926,12 +9926,7 @@ lda {z3}
sta {z1}+2
lda {z3}+1
sta {z1}+3
//FRAGMENT vwuz1=_lo_vduz2
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vduz1=vduz2_setlo_vwuz3
//FRAGMENT vduz1=vduz2_setword0_vwuz3
lda {z3}
sta {z1}
lda {z3}+1
@ -9940,6 +9935,11 @@ lda {z2}+2
sta {z1}+2
lda {z2}+3
sta {z1}+3
//FRAGMENT vwuz1=_lo_vduz2
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuz1_plus_vwuc1
clc
lda {z1}
@ -9948,7 +9948,7 @@ sta {z1}
lda {z1}+1
adc #>{c1}
sta {z1}+1
//FRAGMENT vduz1=vduz1_setlo_vwuz2
//FRAGMENT vduz1=vduz1_setword0_vwuz2
lda {z2}
sta {z1}
lda {z2}+1
@ -11354,6 +11354,90 @@ inx
ldy {c1}
iny
iny
//FRAGMENT pwuc1_derefidx_vbuz1=pwuc2_derefidx_vbuz2
ldx {z1}
ldy {z2}
lda {c2},y
sta {c1},x
lda {c2}+1,y
sta {c1}+1,x
//FRAGMENT pwuc1_derefidx_vbuz1=pwuc1_derefidx_vbuz1_setbyte0_vbuc2
lda #{c2}
ldy {z1}
sta {c1},y
//FRAGMENT pwuc1_derefidx_vbuz1=pwuc2_derefidx_vbuxx
ldy {z1}
lda {c2},x
sta {c1},y
lda {c2}+1,x
sta {c1}+1,y
//FRAGMENT pwuc1_derefidx_vbuz1=pwuc2_derefidx_vbuyy
ldx {z1}
lda {c2},y
sta {c1},x
lda {c2}+1,y
sta {c1}+1,x
//FRAGMENT pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuz1
ldx {z1}
tay
lda {c2},x
sta {c1},y
lda {c2}+1,x
sta {c1}+1,y
//FRAGMENT pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuxx
tay
lda {c2},x
sta {c1},y
lda {c2}+1,x
sta {c1}+1,y
//FRAGMENT pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuyy
tax
lda {c2},y
sta {c1},x
lda {c2}+1,y
sta {c1}+1,x
//FRAGMENT pwuc1_derefidx_vbuxx=pwuc2_derefidx_vbuz1
ldy {z1}
lda {c2},y
sta {c1},x
lda {c2}+1,y
sta {c1}+1,x
//FRAGMENT pwuc1_derefidx_vbuxx=pwuc2_derefidx_vbuxx
txa
tay
lda {c2},y
sta {c1},x
lda {c2}+1,y
sta {c1}+1,x
//FRAGMENT pwuc1_derefidx_vbuxx=pwuc2_derefidx_vbuyy
lda {c2},y
sta {c1},x
lda {c2}+1,y
sta {c1}+1,x
//FRAGMENT pwuc1_derefidx_vbuyy=pwuc2_derefidx_vbuz1
ldx {z1}
lda {c2},x
sta {c1},y
lda {c2}+1,x
sta {c1}+1,y
//FRAGMENT pwuc1_derefidx_vbuyy=pwuc2_derefidx_vbuxx
lda {c2},x
sta {c1},y
lda {c2}+1,x
sta {c1}+1,y
//FRAGMENT pwuc1_derefidx_vbuyy=pwuc2_derefidx_vbuyy
tya
tax
lda {c2},x
sta {c1},y
lda {c2}+1,x
sta {c1}+1,y
//FRAGMENT pwuc1_derefidx_vbuxx=pwuc1_derefidx_vbuxx_setbyte0_vbuc2
lda #{c2}
sta {c1},x
//FRAGMENT pwuc1_derefidx_vbuyy=pwuc1_derefidx_vbuyy_setbyte0_vbuc2
lda #{c2}
sta {c1},y
//FRAGMENT 0_neq_vwuz1_then_la1
lda {z1}
ora {z1}+1
@ -11957,145 +12041,6 @@ and {c1},y
tya
ldy {z1}
and {c1},y
//FRAGMENT pbuz1=pbuc1_sethi_vbuz2
lda {z2}
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT pbuz1=pbuz2_setlo_vbuz3
lda {z3}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuc1_sethi_vbuz2
lda {z2}
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT vwuz1=vwuz2_setlo_vbuz3
lda {z3}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vbuz1=_deref_pbuz2_bor_pbuc1_derefidx_vbuz3
ldy #0
lda ({z2}),y
ldy {z3}
ora {c1},y
sta {z1}
//FRAGMENT pbuz1=pbuc1_sethi_vbuaa
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT pbuz1=pbuc1_sethi_vbuxx
stx {z1}+1
ldx #<{c1}
stx {z1}
//FRAGMENT pbuz1=pbuz2_setlo_vbuaa
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT pbuz1=pbuz2_setlo_vbuxx
stx {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT pbuz1=pbuz2_setlo_vbuyy
sty {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuc1_sethi_vbuaa
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT vwuz1=vwuc1_sethi_vbuxx
stx {z1}+1
ldx #<{c1}
stx {z1}
//FRAGMENT vwuz1=vwuz2_setlo_vbuaa
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuz2_setlo_vbuxx
stx {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuz2_setlo_vbuyy
sty {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vbuz1=_deref_pbuz2_bor_pbuc1_derefidx_vbuxx
lda {c1},x
ldy #0
ora ({z2}),y
sta {z1}
//FRAGMENT vbuz1=_deref_pbuz2_bor_pbuc1_derefidx_vbuyy
lda {c1},y
ldy #0
ora ({z2}),y
sta {z1}
//FRAGMENT vbuaa=_deref_pbuz1_bor_pbuc1_derefidx_vbuz2
ldy #0
lda ({z1}),y
ldy {z2}
ora {c1},y
//FRAGMENT vbuaa=_deref_pbuz1_bor_pbuc1_derefidx_vbuxx
lda {c1},x
ldy #0
ora ({z1}),y
//FRAGMENT vbuaa=_deref_pbuz1_bor_pbuc1_derefidx_vbuyy
lda {c1},y
ldy #0
ora ({z1}),y
//FRAGMENT vbuxx=_deref_pbuz1_bor_pbuc1_derefidx_vbuz2
ldx {z2}
lda {c1},x
ldy #0
ora ({z1}),y
tax
//FRAGMENT vbuxx=_deref_pbuz1_bor_pbuc1_derefidx_vbuxx
lda {c1},x
ldy #0
ora ({z1}),y
tax
//FRAGMENT vbuxx=_deref_pbuz1_bor_pbuc1_derefidx_vbuyy
lda {c1},y
ldy #0
ora ({z1}),y
tax
//FRAGMENT vbuyy=_deref_pbuz1_bor_pbuc1_derefidx_vbuz2
ldy #0
lda ({z1}),y
ldy {z2}
ora {c1},y
tay
//FRAGMENT vbuyy=_deref_pbuz1_bor_pbuc1_derefidx_vbuxx
lda {c1},x
ldy #0
ora ({z1}),y
tay
//FRAGMENT vbuyy=_deref_pbuz1_bor_pbuc1_derefidx_vbuyy
lda {c1},y
ldy #0
ora ({z1}),y
tay
//FRAGMENT pbuz1=pbuc1_sethi_vbuyy
sty {z1}+1
ldy #<{c1}
sty {z1}
//FRAGMENT vwuz1=vwuc1_sethi_vbuyy
sty {z1}+1
ldy #<{c1}
sty {z1}
//FRAGMENT vbuyy=_lo_pbuz1
ldy {z1}
//FRAGMENT vbuz1=vbuz2_bor__lo_pbuz3
lda {z2}
ora {z3}
sta {z1}
//FRAGMENT pbuz1=pbuz1_setlo_vbuaa
sta {z1}
//FRAGMENT vwuz1=vwuz1_setlo_vbuaa
sta {z1}
//FRAGMENT vdsz1_lt_0_then_la1
lda {z1}+3
bmi {la1}
@ -13843,3 +13788,97 @@ sta {c1},x
lda #{c2}
ora {c1},y
sta {c1},y
//FRAGMENT pbuz1=pbuc1_setbyte1_vbuz2
lda {z2}
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT pbuz1=pbuz2_setbyte0_vbuz3
NO_SYNTHESIS
//FRAGMENT vwuz1=vwuc1_setbyte1_vbuz2
lda {z2}
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT vwuz1=vwuz2_setbyte0_vbuz3
lda {z3}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vbuz1=_deref_pbuz2_bor_pbuc1_derefidx_vbuz3
ldy #0
lda ({z2}),y
ldy {z3}
ora {c1},y
sta {z1}
//FRAGMENT pbuz1=pbuc1_setbyte1_vbuaa
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT pbuz1=pbuc1_setbyte1_vbuxx
txa
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT pbuz1=pbuc1_setbyte1_vbuyy
tya
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT pbuz1=pbuz2_setbyte0_vbuaa
NO_SYNTHESIS
//FRAGMENT pbuz1=pbuz2_setbyte0_vbuxx
NO_SYNTHESIS
//FRAGMENT pbuz1=pbuz2_setbyte0_vbuyy
NO_SYNTHESIS
//FRAGMENT vwuz1=vwuc1_setbyte1_vbuaa
sta {z1}+1
lda #<{c1}
sta {z1}
//FRAGMENT vwuz1=vwuc1_setbyte1_vbuxx
stx {z1}+1
ldx #<{c1}
stx {z1}
//FRAGMENT vwuz1=vwuz2_setbyte0_vbuaa
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuz2_setbyte0_vbuxx
stx {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vwuz1=vwuz2_setbyte0_vbuyy
sty {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vbuaa=_deref_pbuz1_bor_pbuc1_derefidx_vbuz2
ldy #0
lda ({z1}),y
ldy {z2}
ora {c1},y
//FRAGMENT vbuxx=_deref_pbuz1_bor_pbuc1_derefidx_vbuz2
ldx {z2}
lda {c1},x
ldy #0
ora ({z1}),y
tax
//FRAGMENT vbuyy=_deref_pbuz1_bor_pbuc1_derefidx_vbuz2
ldy #0
lda ({z1}),y
ldy {z2}
ora {c1},y
tay
//FRAGMENT vwuz1=vwuc1_setbyte1_vbuyy
sty {z1}+1
ldy #<{c1}
sty {z1}
//FRAGMENT vbuyy=_lo_pbuz1
ldy {z1}
//FRAGMENT vbuz1=vbuz2_bor__lo_pbuz3
lda {z2}
ora {z3}
sta {z1}
//FRAGMENT pbuz1=pbuz1_setbyte0_vbuaa
sta {z1}
//FRAGMENT vwuz1=vwuz1_setbyte0_vbuaa
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//KICKC FRAGMENT CACHE ee20482c1 ee204a320
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
inc {c1}
//FRAGMENT isr_hardware_all_entry

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//KICKC FRAGMENT CACHE ee20482c1 ee204a320
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}

View File

@ -0,0 +1,3 @@
sta {m1}+1
lda #<{c1}
sta {m1}

View File

@ -0,0 +1 @@
sta {m1}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Binary SetByte0 Operator ( w byte0= b ) */
public class OperatorSetByte0 extends OperatorBinary {
public OperatorSetByte0(int precedence) {
super("byte0=", "_setbyte0_", precedence, false);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
}
@Override
public SymbolType inferType(SymbolType left, SymbolType right) {
return left;
}
}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Binary SetByte1 Operator ( w byte1= b ) */
public class OperatorSetByte1 extends OperatorBinary {
public OperatorSetByte1(int precedence) {
super("byte1=", "_setbyte1_", precedence, false);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
}
@Override
public SymbolType inferType(SymbolType left, SymbolType right) {
return left;
}
}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Binary SetByte2 Operator ( w byte2= b ) */
public class OperatorSetByte2 extends OperatorBinary {
public OperatorSetByte2(int precedence) {
super("byte2=", "_setbyte2_", precedence, false);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
}
@Override
public SymbolType inferType(SymbolType left, SymbolType right) {
return left;
}
}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Binary SetByte3 Operator ( w byte3= b ) */
public class OperatorSetByte3 extends OperatorBinary {
public OperatorSetByte3(int precedence) {
super("byte3=", "_setbyte3_", precedence, false);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
}
@Override
public SymbolType inferType(SymbolType left, SymbolType right) {
return left;
}
}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Binary SetWord0 Operator ( w word0= b ) */
public class OperatorSetWord0 extends OperatorBinary {
public OperatorSetWord0(int precedence) {
super("word0=", "_setword0_", precedence, false);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
}
@Override
public SymbolType inferType(SymbolType left, SymbolType right) {
return left;
}
}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Binary SetWord1 Operator ( w word1= b ) */
public class OperatorSetWord1 extends OperatorBinary {
public OperatorSetWord1(int precedence) {
super("word1=", "_setword1_", precedence, false);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
}
@Override
public SymbolType inferType(SymbolType left, SymbolType right) {
return left;
}
}

View File

@ -18,8 +18,12 @@ public class Operators {
public static final OperatorBinary WORD = new OperatorWord(2);
public static final OperatorBinary DWORD = new OperatorDWord(2);
public static final OperatorBinary DEREF_IDX = new OperatorDerefIdx(2);
public static final OperatorBinary SET_LOWBYTE = new OperatorSetLow(2);
public static final OperatorBinary SET_HIBYTE = new OperatorSetHigh(2);
public static final OperatorBinary SET_BYTE0 = new OperatorSetByte0(2);
public static final OperatorBinary SET_BYTE1 = new OperatorSetByte1(2);
public static final OperatorBinary SET_BYTE2 = new OperatorSetByte2(2);
public static final OperatorBinary SET_BYTE3 = new OperatorSetByte3(2);
public static final OperatorBinary SET_WORD0 = new OperatorSetWord0(2);
public static final OperatorBinary SET_WORD1 = new OperatorSetWord1(2);
public static final OperatorUnary CAST_BYTE = new OperatorCastByte(2);
public static final OperatorUnary CAST_SBYTE = new OperatorCastSByte(2);
public static final OperatorUnary CAST_WORD = new OperatorCastWord(2);
@ -50,7 +54,9 @@ public class Operators {
public static final OperatorBinary LOGIC_AND = new OperatorLogicAnd(12);
public static final OperatorBinary LOGIC_OR = new OperatorLogicOr(13);
public static final OperatorBinary ASSIGNMENT = new OperatorAssignment(14);
@Deprecated
public static final OperatorUnary LOWBYTE = new OperatorGetLow(14);
@Deprecated
public static final OperatorUnary HIBYTE = new OperatorGetHigh(14);
public static final OperatorUnary BYTE0 = new OperatorGetByte0(14);
public static final OperatorUnary BYTE1 = new OperatorGetByte1(14);
@ -99,10 +105,6 @@ public class Operators {
return SHIFT_LEFT;
case ">>":
return SHIFT_RIGHT;
case "lo=":
return SET_LOWBYTE;
case "hi=":
return SET_HIBYTE;
default:
throw new RuntimeException("Unknown operator " + op);
}

View File

@ -2233,7 +2233,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return lValue;
}
private static LValue copyLValue(LValue lValue) {
public static LValue copyLValue(LValue lValue) {
if(lValue instanceof VariableRef) {
return new VariableRef(((VariableRef) lValue).getFullName());
} else if(lValue instanceof LvalueIntermediate) {

View File

@ -45,17 +45,34 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
StatementLValue statementLValue = (StatementLValue) statement;
LvalueIntermediate intermediate = (LvalueIntermediate) statementLValue.getlValue();
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(intermediate.getVariable(), getGraph(), programScope);
final Scope currentScope = programScope.getScope(block.getScope());
if(varAssignments.size() == 1) {
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
if(varAssignment.type.equals(VarAssignments.VarAssignment.Type.STATEMENT_LVALUE) && varAssignment.statementLValue instanceof StatementAssignment) {
StatementAssignment intermediateAssignment = (StatementAssignment) varAssignment.statementLValue;
if(Operators.LOWBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue <x = ...
fixLoHiLValue(programScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_LOWBYTE);
if(Operators.BYTE0.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue byte0(x) = ...
fixLoHiLValue(programScope, currentScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_BYTE0);
intermediates.add(intermediate.getVariable());
} else if(Operators.HIBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue >x = ...
fixLoHiLValue(programScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_HIBYTE);
} else if(Operators.BYTE1.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue byte0(x) = ...
fixLoHiLValue(programScope, currentScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_BYTE1);
intermediates.add(intermediate.getVariable());
} else if(Operators.BYTE2.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue byte0(x) = ...
fixLoHiLValue(programScope, currentScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_BYTE2);
intermediates.add(intermediate.getVariable());
} else if(Operators.BYTE3.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue byte0(x) = ...
fixLoHiLValue(programScope, currentScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_BYTE3);
intermediates.add(intermediate.getVariable());
} else if(Operators.WORD0.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue byte0(x) = ...
fixLoHiLValue(programScope, currentScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_WORD0);
intermediates.add(intermediate.getVariable());
} else if(Operators.WORD1.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
// Found assignment to an intermediate low byte lValue byte0(x) = ...
fixLoHiLValue(programScope, currentScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_WORD1);
intermediates.add(intermediate.getVariable());
}
}
@ -73,21 +90,22 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
private void fixLoHiLValue(
ProgramScope programScope,
Scope currentScope,
ListIterator<Statement> statementsIt,
StatementLValue statementLValue,
LvalueIntermediate intermediate,
StatementAssignment intermediateAssignment,
Operator loHiOperator) {
VariableRef loHiVar = (VariableRef) intermediateAssignment.getrValue2();
Variable intermediateVar = programScope.getVariable(intermediate.getVariable());
Scope currentScope = intermediateVar.getScope();
final RValue intermediateValue = intermediateAssignment.getrValue2();
// Let assignment put value into a tmp Var
SymbolType type = SymbolTypeInference.inferType(programScope, new AssignmentRValue(intermediateAssignment));
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, type, getProgram());
SymbolVariableRef tmpVarRef = tmpVar.getRef();
statementLValue.setlValue((LValue) tmpVarRef);
// Insert an extra "set low" assignment statement
Statement setLoHiAssignment = new StatementAssignment(loHiVar, loHiVar, loHiOperator, tmpVarRef, true, statementLValue.getSource(), new ArrayList<>());
// TODO: Copy intermediateValue
final LValue lValue = Pass0GenerateStatementSequence.copyLValue((LValue) intermediateValue);
Statement setLoHiAssignment = new StatementAssignment(lValue, intermediateValue, loHiOperator, tmpVarRef, true, statementLValue.getSource(), new ArrayList<>());
statementsIt.add(setLoHiAssignment);
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("Fixing lo/hi-lvalue with new tmpVar " + tmpVarRef + " " + statementLValue.toString());

View File

@ -1,6 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ConstantNotLiteral;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.OperatorBinary;
import dk.camelot64.kickc.model.operators.OperatorUnary;
@ -254,6 +257,18 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
return new ConstantBinary(new ConstantBinary(c1, Operators.MULTIPLY, new ConstantInteger(256L)), Operators.PLUS, c2);
case "dw=":
return new ConstantBinary(new ConstantBinary(c1, Operators.MULTIPLY, new ConstantInteger(65536L)), Operators.PLUS, c2);
case "byte0=":
return new ConstantBinary(new ConstantBinary(c1, Operators.BOOL_AND, new ConstantInteger(0xffffff00L)), Operators.BOOL_OR, c2);
case "byte1=":
return new ConstantBinary(new ConstantBinary(c1, Operators.BOOL_AND, new ConstantInteger(0xffff00ffL)), Operators.BOOL_OR, new ConstantBinary(c2, Operators.MULTIPLY, new ConstantInteger(0x100L)));
case "byte2=":
return new ConstantBinary(new ConstantBinary(c1, Operators.BOOL_AND, new ConstantInteger(0xff00ffffL)), Operators.BOOL_OR, new ConstantBinary(c2, Operators.MULTIPLY, new ConstantInteger(0x10000L)));
case "byte3=":
return new ConstantBinary(new ConstantBinary(c1, Operators.BOOL_AND, new ConstantInteger(0x00ffffffL)), Operators.BOOL_OR, new ConstantBinary(c2, Operators.MULTIPLY, new ConstantInteger(0x1000000L)));
case "word0=":
return new ConstantBinary(new ConstantBinary(c1, Operators.BOOL_AND, new ConstantInteger(0xffff0000L)), Operators.BOOL_OR, c2);
case "word1=":
return new ConstantBinary(new ConstantBinary(c1, Operators.BOOL_AND, new ConstantInteger(0x0000ffffL)), Operators.BOOL_OR, new ConstantBinary(c2, Operators.MULTIPLY, new ConstantInteger(0x10000L)));
case "*idx":
// Pointer dereference - not constant
return null;

View File

@ -21,10 +21,10 @@ unsigned int mul8u(char a, char b) {
signed int mul8s(signed char a, signed char b) {
unsigned int m = mul8u((char)a, (char) b);
if(a<0) {
>m = (>m)-(char)b;
BYTE1(m) = BYTE1(m)-(char)b;
}
if(b<0) {
>m = (>m)-(char)a;
BYTE1(m) = BYTE1(m)-(char)a;
}
return (signed int)m;
}
@ -34,7 +34,7 @@ signed int mul8s(signed char a, signed char b) {
signed int mul8su(signed char a, char b) {
unsigned int m = mul8u((char)a, (char) b);
if(a<0) {
>m = (>m)-(char)b;
BYTE1(m) = BYTE1(m)-(char)b;
}
return (signed int)m;
}
@ -58,10 +58,10 @@ unsigned long mul16u(unsigned int a, unsigned int b) {
signed long mul16s(signed int a, signed int b) {
unsigned long m = mul16u((unsigned int)a, (unsigned int) b);
if(a<0) {
>m = (>m)-(unsigned int)b;
WORD1(m) = WORD1(m)-(unsigned int)b;
}
if(b<0) {
>m = (>m)-(unsigned int)a;
WORD1(m) = WORD1(m)-(unsigned int)a;
}
return (signed long)m;
}

View File

@ -89,6 +89,11 @@ public class TestProgramsFast extends TestPrograms {
compileAndCompare("init-value-npe.c");
}
@Test
public void testOperatorByte0LValue1() throws IOException {
compileAndCompare("operator-byte0-lvalue-1.c");
}
@Test
public void testOperatorByte0Iintializer() throws IOException {
compileAndCompare("operator-byte0-initializer.c");

View File

@ -52,10 +52,10 @@ const byte plot_bit[256];
void plot(byte x, byte y) {
byte* plotter_x = (byte*)0;
word plotter_y = 0;
>plotter_x = plot_xhi[x]; // Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
<plotter_x = plot_xlo[x];
>plotter_y = plot_yhi[y];
<plotter_y = plot_ylo[y];
BYTE1(plotter_x) = plot_xhi[x]; // Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
BYTE0(plotter_x) = plot_xlo[x];
BYTE1(plotter_y) = plot_yhi[y];
BYTE0(plotter_y) = plot_ylo[y];
byte* plotter = plotter_x+plotter_y;
*plotter = *plotter | plot_bit[x];
}

View File

@ -0,0 +1,21 @@
// Test using operator byte0() in an lvalue
void main() {
unsigned int * const SCREEN = (unsigned int *)0x0400;
unsigned int w = 12345;
unsigned int ws[] = { 23456, 34567 };
char i = 0;
SCREEN[i++] = w;
BYTE0(w) = 1;
SCREEN[i++] = w;
BYTE1(w) = 2;
SCREEN[i++] = w;
for(char j=0;j<2;j++) {
SCREEN[i++] = ws[j];
BYTE0(ws[j]) = 2;
SCREEN[i++] = ws[j];
}
}

View File

@ -4,21 +4,21 @@ void main() {
print_cls();
for( dword dw = $12345678; dw != $12345690; dw++ ) {
dword dw2 = dw;
>dw2 = (>dw) + $1111; // Test set/get high word of dword
<dw2 = (<dw) + $1111; // Test set/get low word of dword
WORD1(dw2) = WORD1(dw) + $1111; // Test set/get high word of dword
WORD0(dw2) = WORD0(dw) + $1111; // Test set/get low word of dword
print_ulong(dw2);
print_char(' ');
print_uint(>dw2); // Test get high word of dword
print_uint(WORD1(dw2)); // Test get high word of dword
print_char(' ');
print_uint(<dw2); // Test get low word of dword
print_uint(WORD0(dw2)); // Test get low word of dword
print_char(' ');
print_uchar(> >dw2); // Test get high high byte of dword
print_uchar(BYTE3(dw2)); // Test get high high byte of dword
print_char(' ');
print_uchar(< >dw2); // Test get low high byte of dword
print_uchar(BYTE2(dw2)); // Test get low high byte of dword
print_char(' ');
print_uchar(> <dw2); // Test get high low byte of dword
print_uchar(BYTE1(dw2)); // Test get high low byte of dword
print_char(' ');
print_uchar(< <dw2); // Test get low low byte of dword
print_uchar(BYTE0(dw2)); // Test get low low byte of dword
print_ln();
}
}

View File

@ -48,8 +48,8 @@ main: {
jmp __b1
}
init_screen: {
.label b = 6
.label c = 4
.label b = 7
.label c = 5
lda #<BITMAP
sta.z b
lda #>BITMAP
@ -101,7 +101,7 @@ init_screen: {
}
init_plot_tables: {
.label __9 = 2
.label yoffs = 6
.label yoffs = 7
ldy #$80
ldx #0
__b1:
@ -168,47 +168,51 @@ init_plot_tables: {
rts
}
plots: {
ldx #0
.label i = 2
lda #0
sta.z i
__b1:
// for(byte i=0; i<plots_cnt;i++)
cpx #plots_cnt
lda.z i
cmp #plots_cnt
bcc __b2
// }
rts
__b2:
// plot(plots_x[i], plots_y[i])
lda plots_x,x
ldy.z i
lda plots_x,y
sta.z plot.x
lda plots_y,x
lda plots_y,y
sta.z plot.y
jsr plot
// for(byte i=0; i<plots_cnt;i++)
inx
inc.z i
jmp __b1
}
// plot(byte zp(2) x, byte zp(3) y)
// plot(byte zp(3) x, byte zp(4) y)
plot: {
.label x = 2
.label y = 3
.label plotter_x = 4
.label plotter_y = 6
.label plotter = 4
// >plotter_x = plot_xhi[x]
.label x = 3
.label y = 4
.label plotter_x = 5
.label plotter_y = 7
.label plotter = 5
// BYTE1(plotter_x) = plot_xhi[x]
ldy.z x
lda plot_xhi,y
sta.z plotter_x+1
lda #<0
sta.z plotter_x
// <plotter_x = plot_xlo[x]
// BYTE0(plotter_x) = plot_xlo[x]
lda plot_xlo,y
sta.z plotter_x
// >plotter_y = plot_yhi[y]
// BYTE1(plotter_y) = plot_yhi[y]
ldy.z y
lda plot_yhi,y
sta.z plotter_y+1
lda #<0
sta.z plotter_y
// <plotter_y = plot_ylo[y]
// BYTE0(plotter_y) = plot_ylo[y]
lda plot_ylo,y
sta.z plotter_y
// byte* plotter = plotter_x+plotter_y

View File

@ -114,13 +114,13 @@ plots::@3: scope:[plots] from plots::@2
void plot(byte plot::x , byte plot::y)
plot: scope:[plot] from plots::@2
[54] plot::$6 = plot_xhi[plot::x#0]
[55] plot::plotter_x#1 = (byte*) 0 hi= plot::$6
[55] plot::plotter_x#1 = (byte*) 0 byte1= plot::$6
[56] plot::$7 = plot_xlo[plot::x#0]
[57] plot::plotter_x#2 = plot::plotter_x#1 lo= plot::$7
[57] plot::plotter_x#2 = plot::plotter_x#1 byte0= plot::$7
[58] plot::$8 = plot_yhi[plot::y#0]
[59] plot::plotter_y#1 = 0 hi= plot::$8
[59] plot::plotter_y#1 = 0 byte1= plot::$8
[60] plot::$9 = plot_ylo[plot::y#0]
[61] plot::plotter_y#2 = plot::plotter_y#1 lo= plot::$9
[61] plot::plotter_y#2 = plot::plotter_y#1 byte0= plot::$9
[62] plot::plotter#0 = plot::plotter_x#2 + plot::plotter_y#2
[63] plot::$5 = *plot::plotter#0 | plot_bit[plot::x#0]
[64] *plot::plotter#0 = plot::$5

File diff suppressed because it is too large Load Diff

View File

@ -25,16 +25,16 @@ byte init_plot_tables::y
byte init_plot_tables::y#1 reg byte x 151.5
byte init_plot_tables::y#2 reg byte x 50.5
byte* init_plot_tables::yoffs
byte* init_plot_tables::yoffs#1 yoffs zp[2]:6 202.0
byte* init_plot_tables::yoffs#2 yoffs zp[2]:6 63.125
byte* init_plot_tables::yoffs#4 yoffs zp[2]:6 101.0
byte* init_plot_tables::yoffs#1 yoffs zp[2]:7 202.0
byte* init_plot_tables::yoffs#2 yoffs zp[2]:7 63.125
byte* init_plot_tables::yoffs#4 yoffs zp[2]:7 101.0
void init_screen()
byte* init_screen::b
byte* init_screen::b#1 b zp[2]:6 202.0
byte* init_screen::b#2 b zp[2]:6 134.66666666666666
byte* init_screen::b#1 b zp[2]:7 202.0
byte* init_screen::b#2 b zp[2]:7 134.66666666666666
byte* init_screen::c
byte* init_screen::c#1 c zp[2]:4 202.0
byte* init_screen::c#2 c zp[2]:4 134.66666666666666
byte* init_screen::c#1 c zp[2]:5 202.0
byte* init_screen::c#2 c zp[2]:5 134.66666666666666
void main()
void plot(byte plot::x , byte plot::y)
byte~ plot::$5 reg byte a 200002.0
@ -43,17 +43,17 @@ byte~ plot::$7 reg byte a 200002.0
byte~ plot::$8 reg byte a 200002.0
byte~ plot::$9 reg byte a 200002.0
byte* plot::plotter
byte* plot::plotter#0 plotter zp[2]:4 150001.5
byte* plot::plotter#0 plotter zp[2]:5 150001.5
byte* plot::plotter_x
byte* plot::plotter_x#1 plotter_x zp[2]:4 100001.0
byte* plot::plotter_x#2 plotter_x zp[2]:4 40000.4
byte* plot::plotter_x#1 plotter_x zp[2]:5 100001.0
byte* plot::plotter_x#2 plotter_x zp[2]:5 40000.4
word plot::plotter_y
word plot::plotter_y#1 plotter_y zp[2]:6 100001.0
word plot::plotter_y#2 plotter_y zp[2]:6 200002.0
word plot::plotter_y#1 plotter_y zp[2]:7 100001.0
word plot::plotter_y#2 plotter_y zp[2]:7 200002.0
byte plot::x
byte plot::x#0 x zp[1]:2 28182.181818181816
byte plot::x#0 x zp[1]:3 28182.181818181816
byte plot::y
byte plot::y#0 y zp[1]:3 30000.428571428572
byte plot::y#0 y zp[1]:4 30000.428571428572
constant const byte* plot_bit[$100] = { fill( $100, 0) }
constant const byte* plot_xhi[$100] = { fill( $100, 0) }
constant const byte* plot_xlo[$100] = { fill( $100, 0) }
@ -61,8 +61,8 @@ constant const byte* plot_yhi[$100] = { fill( $100, 0) }
constant const byte* plot_ylo[$100] = { fill( $100, 0) }
void plots()
byte plots::i
byte plots::i#1 reg byte x 20002.0
byte plots::i#2 reg byte x 10001.0
byte plots::i#1 i zp[1]:2 20002.0
byte plots::i#2 i zp[1]:2 10001.0
constant byte plots_cnt = 8
constant byte* plots_x[] = { $3c, $50, $6e, $50, $3c, $28, $a, $28 }
constant byte* plots_y[] = { $a, $28, $3c, $50, $6e, $50, $3c, $28 }
@ -70,17 +70,17 @@ constant byte* plots_y[] = { $a, $28, $3c, $50, $6e, $50, $3c, $28 }
reg byte x [ init_plot_tables::x#2 init_plot_tables::x#1 ]
reg byte y [ init_plot_tables::bits#3 init_plot_tables::bits#4 init_plot_tables::bits#1 ]
reg byte x [ init_plot_tables::y#2 init_plot_tables::y#1 ]
reg byte x [ plots::i#2 plots::i#1 ]
reg byte a [ init_plot_tables::$0 ]
zp[1]:2 [ init_plot_tables::$9 plots::i#2 plots::i#1 ]
reg byte a [ init_plot_tables::$6 ]
reg byte a [ init_plot_tables::$7 ]
reg byte a [ init_plot_tables::$8 ]
zp[1]:2 [ plot::x#0 init_plot_tables::$9 ]
zp[1]:3 [ plot::y#0 ]
zp[1]:3 [ plot::x#0 ]
zp[1]:4 [ plot::y#0 ]
reg byte a [ plot::$6 ]
zp[2]:4 [ plot::plotter_x#1 plot::plotter_x#2 plot::plotter#0 init_screen::c#2 init_screen::c#1 ]
zp[2]:5 [ plot::plotter_x#1 plot::plotter_x#2 plot::plotter#0 init_screen::c#2 init_screen::c#1 ]
reg byte a [ plot::$7 ]
reg byte a [ plot::$8 ]
zp[2]:6 [ plot::plotter_y#1 plot::plotter_y#2 init_plot_tables::yoffs#2 init_plot_tables::yoffs#4 init_plot_tables::yoffs#1 init_screen::b#2 init_screen::b#1 ]
zp[2]:7 [ plot::plotter_y#1 plot::plotter_y#2 init_plot_tables::yoffs#2 init_plot_tables::yoffs#4 init_plot_tables::yoffs#1 init_screen::b#2 init_screen::b#1 ]
reg byte a [ plot::$9 ]
reg byte a [ plot::$5 ]

View File

@ -0,0 +1,72 @@
// Test using operator byte0() in an lvalue
// Commodore 64 PRG executable file
.file [name="operator-byte0-lvalue-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const SIZEOF_WORD = 2
.segment Code
main: {
.label SCREEN = $400
.label i = 3
.label j = 2
// SCREEN[i++] = w
lda #<$3039
sta SCREEN
lda #>$3039
sta SCREEN+1
lda #<$3039&$ffffff00|1
sta SCREEN+1*SIZEOF_WORD
lda #>$3039&$ffffff00|1
sta SCREEN+1*SIZEOF_WORD+1
lda #<($3039&$ffffff00|1)&$ffff00ff|2*$100
sta SCREEN+2*SIZEOF_WORD
lda #>($3039&$ffffff00|1)&$ffff00ff|2*$100
sta SCREEN+2*SIZEOF_WORD+1
lda #3
sta.z i
lda #0
sta.z j
__b1:
// for(char j=0;j<2;j++)
lda.z j
cmp #2
bcc __b2
// }
rts
__b2:
// SCREEN[i++] = ws[j]
lda.z j
asl
tax
lda.z i
asl
tay
lda ws,x
sta SCREEN,y
lda ws+1,x
sta SCREEN+1,y
// SCREEN[i++] = ws[j];
inc.z i
// BYTE0(ws[j]) = 2
lda #2
sta ws,x
// SCREEN[i++] = ws[j]
lda.z i
asl
tay
lda ws,x
sta SCREEN,y
lda ws+1,x
sta SCREEN+1,y
// SCREEN[i++] = ws[j];
inc.z i
// for(char j=0;j<2;j++)
inc.z j
jmp __b1
.segment Data
ws: .word $5ba0, $8707
}

View File

@ -0,0 +1,26 @@
void main()
main: scope:[main] from
[0] *main::SCREEN = $3039
[1] *(main::SCREEN+1*SIZEOF_WORD) = $3039&$ffffff00|1
[2] *(main::SCREEN+2*SIZEOF_WORD) = $3039&$ffffff00|1&$ffff00ff|2*$100
to:main::@1
main::@1: scope:[main] from main main::@2
[3] main::i#6 = phi( main/3, main::@2/main::i#5 )
[3] main::j#2 = phi( main/0, main::@2/main::j#1 )
[4] if(main::j#2<2) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[5] return
to:@return
main::@2: scope:[main] from main::@1
[6] main::$12 = main::j#2 << 1
[7] main::$11 = main::i#6 << 1
[8] main::SCREEN[main::$11] = main::ws[main::$12]
[9] main::i#4 = ++ main::i#6
[10] main::ws[main::$12] = main::ws[main::$12] byte0= 2
[11] main::$14 = main::i#4 << 1
[12] main::SCREEN[main::$14] = main::ws[main::$12]
[13] main::i#5 = ++ main::i#4
[14] main::j#1 = ++ main::j#2
to:main::@1

View File

@ -0,0 +1,579 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
main::w#0 = $3039
main::i#0 = 0
main::$7 = main::i#0 * SIZEOF_WORD
main::SCREEN[main::$7] = main::w#0
main::i#1 = ++ main::i#0
main::$4 = 1
main::w#1 = main::w#0 byte0= main::$4
main::$8 = main::i#1 * SIZEOF_WORD
main::SCREEN[main::$8] = main::w#1
main::i#2 = ++ main::i#1
main::$5 = 2
main::w#2 = main::w#1 byte1= main::$5
main::$9 = main::i#2 * SIZEOF_WORD
main::SCREEN[main::$9] = main::w#2
main::i#3 = ++ main::i#2
main::j#0 = 0
to:main::@1
main::@1: scope:[main] from main main::@2
main::i#7 = phi( main/main::i#3, main::@2/main::i#5 )
main::j#2 = phi( main/main::j#0, main::@2/main::j#1 )
main::$2 = main::j#2 < 2
if(main::$2) goto main::@2
to:main::@return
main::@2: scope:[main] from main::@1
main::i#6 = phi( main::@1/main::i#7 )
main::j#3 = phi( main::@1/main::j#2 )
main::$10 = main::j#3 * SIZEOF_WORD
main::$11 = main::i#6 * SIZEOF_WORD
main::SCREEN[main::$11] = main::ws[main::$10]
main::i#4 = ++ main::i#6
main::$6 = 2
main::$12 = main::j#3 * SIZEOF_WORD
main::ws[main::$12] = main::ws[main::$12] byte0= main::$6
main::$13 = main::j#3 * SIZEOF_WORD
main::$14 = main::i#4 * SIZEOF_WORD
main::SCREEN[main::$14] = main::ws[main::$13]
main::i#5 = ++ main::i#4
main::j#1 = ++ main::j#3
to:main::@1
main::@return: scope:[main] from main::@1
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
constant byte SIZEOF_WORD = 2
void __start()
void main()
byte~ main::$10
byte~ main::$11
byte~ main::$12
byte~ main::$13
byte~ main::$14
bool~ main::$2
byte~ main::$4
byte~ main::$5
byte~ main::$6
byte~ main::$7
byte~ main::$8
byte~ main::$9
constant word* const main::SCREEN = (word*)$400
byte main::i
byte main::i#0
byte main::i#1
byte main::i#2
byte main::i#3
byte main::i#4
byte main::i#5
byte main::i#6
byte main::i#7
byte main::j
byte main::j#0
byte main::j#1
byte main::j#2
byte main::j#3
word main::w
word main::w#0
word main::w#1
word main::w#2
constant word* main::ws[] = { $5ba0, $8707 }
Adding number conversion cast (unumber) 1 in main::$4 = 1
Adding number conversion cast (unumber) 2 in main::$5 = 2
Adding number conversion cast (unumber) 2 in main::$2 = main::j#2 < 2
Adding number conversion cast (unumber) 2 in main::$6 = 2
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast main::$4 = (unumber)1
Inlining cast main::$5 = (unumber)2
Inlining cast main::$6 = (unumber)2
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (word*) 1024
Simplifying constant integer cast 1
Simplifying constant integer cast 2
Simplifying constant integer cast 2
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias main::j#2 = main::j#3
Alias main::i#6 = main::i#7
Successful SSA optimization Pass2AliasElimination
Identified duplicate assignment right side [25] main::$12 = main::j#2 * SIZEOF_WORD
Identified duplicate assignment right side [27] main::$13 = main::j#2 * SIZEOF_WORD
Successful SSA optimization Pass2DuplicateRValueIdentification
Simple Condition main::$2 [18] if(main::j#2<2) goto main::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::w#0 = $3039
Constant main::i#0 = 0
Constant main::$4 = 1
Constant main::$5 = 2
Constant main::j#0 = 0
Constant main::$6 = 2
Successful SSA optimization Pass2ConstantIdentification
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Alias main::$12 = main::$10 main::$13
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [0] main::$7 = main::i#0 * SIZEOF_WORD
Constant right-side identified [2] main::i#1 = ++ main::i#0
Constant right-side identified [3] main::w#1 = main::w#0 byte0= main::$4
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::$7 = main::i#0*SIZEOF_WORD
Constant main::i#1 = ++main::i#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero main::i#0*SIZEOF_WORD in
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero main::SCREEN in [1] main::SCREEN[main::$7] = main::w#0
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant main::$7
Successful SSA optimization PassNEliminateUnusedVars
Adding number conversion cast (unumber) main::w#0&$ffffff00|main::$4 in main::w#1 = main::w#0&$ffffff00|main::$4
Adding number conversion cast (unumber) main::w#0&$ffffff00 in main::w#1 = ((unumber)) main::w#0&$ffffff00|main::$4
Adding number conversion cast (unumber) $ffffff00 in main::w#1 = ((unumber)) (unumber)main::w#0&$ffffff00|main::$4
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast main::w#1 = (unumber)(unumber)main::w#0&(unumber)$ffffff00|main::$4
Successful SSA optimization Pass2InlineCast
Simplifying constant integer cast (unumber)main::w#0&(unumber)$ffffff00|main::$4
Simplifying constant integer cast main::w#0&(unumber)$ffffff00
Simplifying constant integer cast $ffffff00
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (dword) $ffffff00
Successful SSA optimization PassNFinalizeNumberTypeConversions
Constant right-side identified [2] main::$8 = main::i#1 * SIZEOF_WORD
Constant right-side identified [4] main::i#2 = ++ main::i#1
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::w#1 = main::w#0&$ffffff00|main::$4
Constant main::$8 = main::i#1*SIZEOF_WORD
Constant main::i#2 = ++main::i#1
Successful SSA optimization Pass2ConstantIdentification
Constant right-side identified [2] main::w#2 = main::w#1 byte1= main::$5
Constant right-side identified [3] main::$9 = main::i#2 * SIZEOF_WORD
Constant right-side identified [5] main::i#3 = ++ main::i#2
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::$9 = main::i#2*SIZEOF_WORD
Constant main::i#3 = ++main::i#2
Successful SSA optimization Pass2ConstantIdentification
Adding number conversion cast (unumber) main::w#1&$ffff00ff|main::$5*$100 in main::w#2 = main::w#1&$ffff00ff|main::$5*$100
Adding number conversion cast (unumber) $ffff00ff in main::w#2 = ((unumber)) main::w#1&$ffff00ff|main::$5*$100
Adding number conversion cast (unumber) $100 in main::w#2 = ((unumber)) main::w#1&(unumber)$ffff00ff|main::$5*$100
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast main::w#2 = (unumber)main::w#1&(unumber)$ffff00ff|main::$5*(unumber)$100
Successful SSA optimization Pass2InlineCast
Simplifying constant integer cast main::w#1&(unumber)$ffff00ff|main::$5*(unumber)$100
Simplifying constant integer cast $ffff00ff
Simplifying constant integer cast $100
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (dword) $ffff00ff
Finalized unsigned number type (word) $100
Successful SSA optimization PassNFinalizeNumberTypeConversions
Constant main::w#2 = main::w#1&$ffff00ff|main::$5*$100
Successful SSA optimization Pass2ConstantIdentification
Rewriting multiplication to use shift [5] main::$12 = main::j#2 * SIZEOF_WORD
Rewriting multiplication to use shift [6] main::$11 = main::i#6 * SIZEOF_WORD
Rewriting multiplication to use shift [10] main::$14 = main::i#4 * SIZEOF_WORD
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with different constant siblings main::w#0
Inlining constant with var siblings main::i#0
Inlining constant with var siblings main::j#0
Inlining constant with var siblings main::i#1
Inlining constant with different constant siblings main::w#1
Inlining constant with var siblings main::i#2
Inlining constant with var siblings main::i#3
Inlining constant with different constant siblings main::w#2
Constant inlined main::i#3 = ++++++0
Constant inlined main::w#1 = $3039&$ffffff00|1
Constant inlined main::w#2 = $3039&$ffffff00|1&$ffff00ff|2*$100
Constant inlined main::w#0 = $3039
Constant inlined main::$5 = 2
Constant inlined main::i#0 = 0
Constant inlined main::$6 = 2
Constant inlined main::i#2 = ++++0
Constant inlined main::$4 = 1
Constant inlined main::j#0 = 0
Constant inlined main::i#1 = ++0
Constant inlined main::$9 = ++++0*SIZEOF_WORD
Constant inlined main::$8 = ++0*SIZEOF_WORD
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(main::SCREEN+++0*SIZEOF_WORD)
Consolidated array index constant in *(main::SCREEN+++++0*SIZEOF_WORD)
Successful SSA optimization Pass2ConstantAdditionElimination
Simplifying constant integer increment ++0
Simplifying constant integer increment ++0
Simplifying constant integer increment ++1
Successful SSA optimization Pass2ConstantSimplification
Simplifying constant integer increment ++1
Simplifying constant integer increment ++2
Successful SSA optimization Pass2ConstantSimplification
CALL GRAPH
Created 2 initial phi equivalence classes
Coalesced [15] main::j#4 = main::j#1
Coalesced [16] main::i#8 = main::i#5
Coalesced down to 2 phi equivalence classes
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *main::SCREEN = $3039
[1] *(main::SCREEN+1*SIZEOF_WORD) = $3039&$ffffff00|1
[2] *(main::SCREEN+2*SIZEOF_WORD) = $3039&$ffffff00|1&$ffff00ff|2*$100
to:main::@1
main::@1: scope:[main] from main main::@2
[3] main::i#6 = phi( main/3, main::@2/main::i#5 )
[3] main::j#2 = phi( main/0, main::@2/main::j#1 )
[4] if(main::j#2<2) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[5] return
to:@return
main::@2: scope:[main] from main::@1
[6] main::$12 = main::j#2 << 1
[7] main::$11 = main::i#6 << 1
[8] main::SCREEN[main::$11] = main::ws[main::$12]
[9] main::i#4 = ++ main::i#6
[10] main::ws[main::$12] = main::ws[main::$12] byte0= 2
[11] main::$14 = main::i#4 << 1
[12] main::SCREEN[main::$14] = main::ws[main::$12]
[13] main::i#5 = ++ main::i#4
[14] main::j#1 = ++ main::j#2
to:main::@1
VARIABLE REGISTER WEIGHTS
void main()
byte~ main::$11 22.0
byte~ main::$12 9.166666666666666
byte~ main::$14 22.0
byte main::i
byte main::i#4 8.25
byte main::i#5 11.0
byte main::i#6 6.6000000000000005
byte main::j
byte main::j#1 22.0
byte main::j#2 4.4
word main::w
Initial phi equivalence classes
[ main::j#2 main::j#1 ]
[ main::i#6 main::i#5 ]
Added variable main::$12 to live range equivalence class [ main::$12 ]
Added variable main::$11 to live range equivalence class [ main::$11 ]
Added variable main::i#4 to live range equivalence class [ main::i#4 ]
Added variable main::$14 to live range equivalence class [ main::$14 ]
Complete equivalence classes
[ main::j#2 main::j#1 ]
[ main::i#6 main::i#5 ]
[ main::$12 ]
[ main::$11 ]
[ main::i#4 ]
[ main::$14 ]
Allocated zp[1]:2 [ main::j#2 main::j#1 ]
Allocated zp[1]:3 [ main::i#6 main::i#5 ]
Allocated zp[1]:4 [ main::$12 ]
Allocated zp[1]:5 [ main::$11 ]
Allocated zp[1]:6 [ main::i#4 ]
Allocated zp[1]:7 [ main::$14 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *main::SCREEN = $3039 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [1] *(main::SCREEN+1*SIZEOF_WORD) = $3039&$ffffff00|1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *(main::SCREEN+2*SIZEOF_WORD) = $3039&$ffffff00|1&$ffff00ff|2*$100 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] main::$12 = main::j#2 << 1 [ main::j#2 main::i#6 main::$12 ] ( [ main::j#2 main::i#6 main::$12 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::j#2 main::j#1 ]
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#6 main::i#5 ]
Statement [7] main::$11 = main::i#6 << 1 [ main::j#2 main::i#6 main::$12 main::$11 ] ( [ main::j#2 main::i#6 main::$12 main::$11 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:4 [ main::$12 ]
Statement [8] main::SCREEN[main::$11] = main::ws[main::$12] [ main::j#2 main::i#6 main::$12 ] ( [ main::j#2 main::i#6 main::$12 ] { } ) always clobbers reg byte a
Statement [10] main::ws[main::$12] = main::ws[main::$12] byte0= 2 [ main::j#2 main::$12 main::i#4 ] ( [ main::j#2 main::$12 main::i#4 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:6 [ main::i#4 ]
Statement [11] main::$14 = main::i#4 << 1 [ main::j#2 main::$12 main::i#4 main::$14 ] ( [ main::j#2 main::$12 main::i#4 main::$14 ] { } ) always clobbers reg byte a
Statement [12] main::SCREEN[main::$14] = main::ws[main::$12] [ main::j#2 main::i#4 ] ( [ main::j#2 main::i#4 ] { } ) always clobbers reg byte a
Statement [0] *main::SCREEN = $3039 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [1] *(main::SCREEN+1*SIZEOF_WORD) = $3039&$ffffff00|1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *(main::SCREEN+2*SIZEOF_WORD) = $3039&$ffffff00|1&$ffff00ff|2*$100 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] main::$12 = main::j#2 << 1 [ main::j#2 main::i#6 main::$12 ] ( [ main::j#2 main::i#6 main::$12 ] { } ) always clobbers reg byte a
Statement [7] main::$11 = main::i#6 << 1 [ main::j#2 main::i#6 main::$12 main::$11 ] ( [ main::j#2 main::i#6 main::$12 main::$11 ] { } ) always clobbers reg byte a
Statement [8] main::SCREEN[main::$11] = main::ws[main::$12] [ main::j#2 main::i#6 main::$12 ] ( [ main::j#2 main::i#6 main::$12 ] { } ) always clobbers reg byte a
Statement [10] main::ws[main::$12] = main::ws[main::$12] byte0= 2 [ main::j#2 main::$12 main::i#4 ] ( [ main::j#2 main::$12 main::i#4 ] { } ) always clobbers reg byte a
Statement [11] main::$14 = main::i#4 << 1 [ main::j#2 main::$12 main::i#4 main::$14 ] ( [ main::j#2 main::$12 main::i#4 main::$14 ] { } ) always clobbers reg byte a
Statement [12] main::SCREEN[main::$14] = main::ws[main::$12] [ main::j#2 main::i#4 ] ( [ main::j#2 main::i#4 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::j#2 main::j#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ main::i#6 main::i#5 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ main::$12 ] : zp[1]:4 , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$11 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:6 [ main::i#4 ] : zp[1]:6 , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::$14 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 26.4: zp[1]:2 [ main::j#2 main::j#1 ] 22: zp[1]:5 [ main::$11 ] 22: zp[1]:7 [ main::$14 ] 17.6: zp[1]:3 [ main::i#6 main::i#5 ] 9.17: zp[1]:4 [ main::$12 ] 8.25: zp[1]:6 [ main::i#4 ]
Uplift Scope []
Uplifting [main] best 1277 combination zp[1]:2 [ main::j#2 main::j#1 ] reg byte a [ main::$11 ] reg byte a [ main::$14 ] zp[1]:3 [ main::i#6 main::i#5 ] zp[1]:4 [ main::$12 ] zp[1]:6 [ main::i#4 ]
Limited combination testing to 100 combinations of 1296 possible.
Uplifting [] best 1277 combination
Attempting to uplift remaining variables inzp[1]:2 [ main::j#2 main::j#1 ]
Uplifting [main] best 1277 combination zp[1]:2 [ main::j#2 main::j#1 ]
Attempting to uplift remaining variables inzp[1]:3 [ main::i#6 main::i#5 ]
Uplifting [main] best 1277 combination zp[1]:3 [ main::i#6 main::i#5 ]
Attempting to uplift remaining variables inzp[1]:4 [ main::$12 ]
Uplifting [main] best 1177 combination reg byte x [ main::$12 ]
Attempting to uplift remaining variables inzp[1]:6 [ main::i#4 ]
Uplifting [main] best 1177 combination zp[1]:6 [ main::i#4 ]
Coalescing zero page register [ zp[1]:3 [ main::i#6 main::i#5 ] ] with [ zp[1]:6 [ main::i#4 ] ] - score: 2
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test using operator byte0() in an lvalue
// Upstart
// Commodore 64 PRG executable file
.file [name="operator-byte0-lvalue-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const SIZEOF_WORD = 2
.segment Code
// main
main: {
.label SCREEN = $400
.label i = 3
.label j = 2
// [0] *main::SCREEN = $3039 -- _deref_pwuc1=vwuc2
lda #<$3039
sta SCREEN
lda #>$3039
sta SCREEN+1
// [1] *(main::SCREEN+1*SIZEOF_WORD) = $3039&$ffffff00|1 -- _deref_pwuc1=vwuc2
lda #<$3039&$ffffff00|1
sta SCREEN+1*SIZEOF_WORD
lda #>$3039&$ffffff00|1
sta SCREEN+1*SIZEOF_WORD+1
// [2] *(main::SCREEN+2*SIZEOF_WORD) = $3039&$ffffff00|1&$ffff00ff|2*$100 -- _deref_pwuc1=vwuc2
lda #<($3039&$ffffff00|1)&$ffff00ff|2*$100
sta SCREEN+2*SIZEOF_WORD
lda #>($3039&$ffffff00|1)&$ffff00ff|2*$100
sta SCREEN+2*SIZEOF_WORD+1
// [3] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [3] phi main::i#6 = 3 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #3
sta.z i
// [3] phi main::j#2 = 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
lda #0
sta.z j
jmp __b1
// main::@1
__b1:
// [4] if(main::j#2<2) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z j
cmp #2
bcc __b2
jmp __breturn
// main::@return
__breturn:
// [5] return
rts
// main::@2
__b2:
// [6] main::$12 = main::j#2 << 1 -- vbuxx=vbuz1_rol_1
lda.z j
asl
tax
// [7] main::$11 = main::i#6 << 1 -- vbuaa=vbuz1_rol_1
lda.z i
asl
// [8] main::SCREEN[main::$11] = main::ws[main::$12] -- pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuxx
tay
lda ws,x
sta SCREEN,y
lda ws+1,x
sta SCREEN+1,y
// [9] main::i#4 = ++ main::i#6 -- vbuz1=_inc_vbuz1
inc.z i
// [10] main::ws[main::$12] = main::ws[main::$12] byte0= 2 -- pwuc1_derefidx_vbuxx=pwuc1_derefidx_vbuxx_setbyte0_vbuc2
lda #2
sta ws,x
// [11] main::$14 = main::i#4 << 1 -- vbuaa=vbuz1_rol_1
lda.z i
asl
// [12] main::SCREEN[main::$14] = main::ws[main::$12] -- pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuxx
tay
lda ws,x
sta SCREEN,y
lda ws+1,x
sta SCREEN+1,y
// [13] main::i#5 = ++ main::i#4 -- vbuz1=_inc_vbuz1
inc.z i
// [14] main::j#1 = ++ main::j#2 -- vbuz1=_inc_vbuz1
inc.z j
// [3] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
__b1_from___b2:
// [3] phi main::i#6 = main::i#5 [phi:main::@2->main::@1#0] -- register_copy
// [3] phi main::j#2 = main::j#1 [phi:main::@2->main::@1#1] -- register_copy
jmp __b1
.segment Data
ws: .word $5ba0, $8707
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from_main:
Removing instruction __breturn:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
constant byte SIZEOF_WORD = 2
void main()
byte~ main::$11 reg byte a 22.0
byte~ main::$12 reg byte x 9.166666666666666
byte~ main::$14 reg byte a 22.0
constant word* const main::SCREEN = (word*) 1024
byte main::i
byte main::i#4 i zp[1]:3 8.25
byte main::i#5 i zp[1]:3 11.0
byte main::i#6 i zp[1]:3 6.6000000000000005
byte main::j
byte main::j#1 j zp[1]:2 22.0
byte main::j#2 j zp[1]:2 4.4
word main::w
constant word* main::ws[] = { $5ba0, $8707 }
zp[1]:2 [ main::j#2 main::j#1 ]
zp[1]:3 [ main::i#6 main::i#5 main::i#4 ]
reg byte x [ main::$12 ]
reg byte a [ main::$11 ]
reg byte a [ main::$14 ]
FINAL ASSEMBLER
Score: 1057
// File Comments
// Test using operator byte0() in an lvalue
// Upstart
// Commodore 64 PRG executable file
.file [name="operator-byte0-lvalue-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const SIZEOF_WORD = 2
.segment Code
// main
main: {
.label SCREEN = $400
.label i = 3
.label j = 2
// SCREEN[i++] = w
// [0] *main::SCREEN = $3039 -- _deref_pwuc1=vwuc2
lda #<$3039
sta SCREEN
lda #>$3039
sta SCREEN+1
// [1] *(main::SCREEN+1*SIZEOF_WORD) = $3039&$ffffff00|1 -- _deref_pwuc1=vwuc2
lda #<$3039&$ffffff00|1
sta SCREEN+1*SIZEOF_WORD
lda #>$3039&$ffffff00|1
sta SCREEN+1*SIZEOF_WORD+1
// [2] *(main::SCREEN+2*SIZEOF_WORD) = $3039&$ffffff00|1&$ffff00ff|2*$100 -- _deref_pwuc1=vwuc2
lda #<($3039&$ffffff00|1)&$ffff00ff|2*$100
sta SCREEN+2*SIZEOF_WORD
lda #>($3039&$ffffff00|1)&$ffff00ff|2*$100
sta SCREEN+2*SIZEOF_WORD+1
// [3] phi from main to main::@1 [phi:main->main::@1]
// [3] phi main::i#6 = 3 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #3
sta.z i
// [3] phi main::j#2 = 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
lda #0
sta.z j
// main::@1
__b1:
// for(char j=0;j<2;j++)
// [4] if(main::j#2<2) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z j
cmp #2
bcc __b2
// main::@return
// }
// [5] return
rts
// main::@2
__b2:
// SCREEN[i++] = ws[j]
// [6] main::$12 = main::j#2 << 1 -- vbuxx=vbuz1_rol_1
lda.z j
asl
tax
// [7] main::$11 = main::i#6 << 1 -- vbuaa=vbuz1_rol_1
lda.z i
asl
// [8] main::SCREEN[main::$11] = main::ws[main::$12] -- pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuxx
tay
lda ws,x
sta SCREEN,y
lda ws+1,x
sta SCREEN+1,y
// SCREEN[i++] = ws[j];
// [9] main::i#4 = ++ main::i#6 -- vbuz1=_inc_vbuz1
inc.z i
// BYTE0(ws[j]) = 2
// [10] main::ws[main::$12] = main::ws[main::$12] byte0= 2 -- pwuc1_derefidx_vbuxx=pwuc1_derefidx_vbuxx_setbyte0_vbuc2
lda #2
sta ws,x
// SCREEN[i++] = ws[j]
// [11] main::$14 = main::i#4 << 1 -- vbuaa=vbuz1_rol_1
lda.z i
asl
// [12] main::SCREEN[main::$14] = main::ws[main::$12] -- pwuc1_derefidx_vbuaa=pwuc2_derefidx_vbuxx
tay
lda ws,x
sta SCREEN,y
lda ws+1,x
sta SCREEN+1,y
// SCREEN[i++] = ws[j];
// [13] main::i#5 = ++ main::i#4 -- vbuz1=_inc_vbuz1
inc.z i
// for(char j=0;j<2;j++)
// [14] main::j#1 = ++ main::j#2 -- vbuz1=_inc_vbuz1
inc.z j
// [3] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
// [3] phi main::i#6 = main::i#5 [phi:main::@2->main::@1#0] -- register_copy
// [3] phi main::j#2 = main::j#1 [phi:main::@2->main::@1#1] -- register_copy
jmp __b1
.segment Data
ws: .word $5ba0, $8707
}
// File Data

View File

@ -0,0 +1,21 @@
constant byte SIZEOF_WORD = 2
void main()
byte~ main::$11 reg byte a 22.0
byte~ main::$12 reg byte x 9.166666666666666
byte~ main::$14 reg byte a 22.0
constant word* const main::SCREEN = (word*) 1024
byte main::i
byte main::i#4 i zp[1]:3 8.25
byte main::i#5 i zp[1]:3 11.0
byte main::i#6 i zp[1]:3 6.6000000000000005
byte main::j
byte main::j#1 j zp[1]:2 22.0
byte main::j#2 j zp[1]:2 4.4
word main::w
constant word* main::ws[] = { $5ba0, $8707 }
zp[1]:2 [ main::j#2 main::j#1 ]
zp[1]:3 [ main::i#6 main::i#5 main::i#4 ]
reg byte x [ main::$12 ]
reg byte a [ main::$11 ]
reg byte a [ main::$14 ]

View File

@ -9,21 +9,17 @@
.segment Basic
:BasicUpstart(main)
.label print_screen = $400
.label print_line_cursor = $10
.label print_char_cursor = $e
.label print_char_cursor_1 = $10
.label print_line_cursor = 8
.label print_char_cursor = $10
.label print_char_cursor_1 = 8
.label print_line_cursor_1 = 6
.segment Code
main: {
.label __3 = 8
.label __6 = $e
.label __16 = $10
.label __20 = $12
.label __24 = $14
.label __28 = $16
.label __32 = 8
.label __33 = $e
.label dw2 = $a
.label __3 = $a
.label __6 = $10
.label __28 = $a
.label __29 = $10
.label dw2 = $c
.label dw = 2
// print_cls()
jsr print_cls
@ -60,43 +56,43 @@ main: {
// }
rts
__b2:
// >dw
// WORD1(dw)
lda.z dw+2
sta.z __3
lda.z dw+3
sta.z __3+1
// >dw2 = (>dw) + $1111
// WORD1(dw2) = WORD1(dw) + $1111
clc
lda.z __32
lda.z __28
adc #<$1111
sta.z __32
lda.z __32+1
sta.z __28
lda.z __28+1
adc #>$1111
sta.z __32+1
sta.z __28+1
lda.z dw
sta.z dw2
lda.z dw+1
sta.z dw2+1
lda.z __32
lda.z __28
sta.z dw2+2
lda.z __32+1
lda.z __28+1
sta.z dw2+3
// <dw
// WORD0(dw)
lda.z dw
sta.z __6
lda.z dw+1
sta.z __6+1
// <dw2 = (<dw) + $1111
// WORD0(dw2) = WORD0(dw) + $1111
clc
lda.z __33
lda.z __29
adc #<$1111
sta.z __33
lda.z __33+1
sta.z __29
lda.z __29+1
adc #>$1111
sta.z __33+1
lda.z __33
sta.z __29+1
lda.z __29
sta.z dw2
lda.z __33+1
lda.z __29+1
sta.z dw2+1
// print_ulong(dw2)
// Test set/get low word of dword
@ -104,7 +100,7 @@ main: {
// print_char(' ')
lda #' '
jsr print_char
// print_uint(>dw2)
// print_uint(WORD1(dw2))
lda.z dw2+2
sta.z print_uint.w
lda.z dw2+3
@ -114,7 +110,7 @@ main: {
// Test get high word of dword
lda #' '
jsr print_char
// print_uint(<dw2)
// print_uint(WORD0(dw2))
lda.z dw2
sta.z print_uint.w
lda.z dw2+1
@ -124,49 +120,29 @@ main: {
// Test get low word of dword
lda #' '
jsr print_char
// >dw2
lda.z dw2+2
sta.z __16
lda.z dw2+3
sta.z __16+1
// print_uchar(> >dw2)
tax
// print_uchar(BYTE3(dw2))
ldx.z dw2+3
jsr print_uchar
// print_char(' ')
// Test get high high byte of dword
lda #' '
jsr print_char
// >dw2
lda.z dw2+2
sta.z __20
lda.z dw2+3
sta.z __20+1
// print_uchar(< >dw2)
ldx.z __20
// print_uchar(BYTE2(dw2))
ldx.z dw2+2
jsr print_uchar
// print_char(' ')
// Test get low high byte of dword
lda #' '
jsr print_char
// <dw2
lda.z dw2
sta.z __24
lda.z dw2+1
sta.z __24+1
// print_uchar(> <dw2)
tax
// print_uchar(BYTE1(dw2))
ldx.z dw2+1
jsr print_uchar
// print_char(' ')
// Test get high low byte of dword
lda #' '
jsr print_char
// <dw2
lda.z dw2
sta.z __28
lda.z dw2+1
sta.z __28+1
// print_uchar(< <dw2)
ldx.z __28
// print_uchar(BYTE0(dw2))
ldx.z dw2
jsr print_uchar
// print_ln()
// Test get low low byte of dword
@ -194,9 +170,9 @@ print_cls: {
rts
}
// Print a unsigned long as HEX
// print_ulong(dword zp($a) dw)
// print_ulong(dword zp($c) dw)
print_ulong: {
.label dw = $a
.label dw = $c
// print_uint(>dw)
lda.z dw+2
sta.z print_uint.w
@ -232,9 +208,9 @@ print_char: {
rts
}
// Print a unsigned int as HEX
// print_uint(word zp(8) w)
// print_uint(word zp($a) w)
print_uint: {
.label w = 8
.label w = $a
// print_uchar(>w)
ldx.z w+1
jsr print_uchar
@ -301,7 +277,7 @@ memset: {
.const num = $3e8
.label str = print_screen
.label end = str+num
.label dst = $10
.label dst = 8
lda #<str
sta.z dst
lda #>str

View File

@ -14,12 +14,12 @@ main::@return: scope:[main] from main::@1
[4] return
to:@return
main::@2: scope:[main] from main::@1
[5] main::$3 = > main::dw#10
[6] main::$32 = main::$3 + $1111
[7] main::dw2#1 = main::dw#10 hi= main::$32
[8] main::$6 = < main::dw#10
[9] main::$33 = main::$6 + $1111
[10] main::dw2#10 = main::dw2#1 lo= main::$33
[5] main::$3 = _word1_ main::dw#10
[6] main::$28 = main::$3 + $1111
[7] main::dw2#1 = main::dw#10 word1= main::$28
[8] main::$6 = _word0_ main::dw#10
[9] main::$29 = main::$6 + $1111
[10] main::dw2#10 = main::dw2#1 word0= main::$29
[11] print_ulong::dw#0 = main::dw2#10
[12] call print_ulong
to:main::@3
@ -28,7 +28,7 @@ main::@3: scope:[main] from main::@2
[14] call print_char
to:main::@4
main::@4: scope:[main] from main::@3
[15] print_uint::w#2 = > main::dw2#10
[15] print_uint::w#2 = _word1_ main::dw2#10
[16] call print_uint
to:main::@5
main::@5: scope:[main] from main::@4
@ -36,7 +36,7 @@ main::@5: scope:[main] from main::@4
[18] call print_char
to:main::@6
main::@6: scope:[main] from main::@5
[19] print_uint::w#3 = < main::dw2#10
[19] print_uint::w#3 = _word0_ main::dw2#10
[20] call print_uint
to:main::@7
main::@7: scope:[main] from main::@6
@ -44,140 +44,136 @@ main::@7: scope:[main] from main::@6
[22] call print_char
to:main::@8
main::@8: scope:[main] from main::@7
[23] main::$16 = > main::dw2#10
[24] print_uchar::b#2 = > main::$16
[25] call print_uchar
[23] print_uchar::b#2 = _byte3_ main::dw2#10
[24] call print_uchar
to:main::@9
main::@9: scope:[main] from main::@8
[26] phi()
[27] call print_char
[25] phi()
[26] call print_char
to:main::@10
main::@10: scope:[main] from main::@9
[28] main::$20 = > main::dw2#10
[29] print_uchar::b#3 = < main::$20
[30] call print_uchar
[27] print_uchar::b#3 = _byte2_ main::dw2#10
[28] call print_uchar
to:main::@11
main::@11: scope:[main] from main::@10
[31] phi()
[32] call print_char
[29] phi()
[30] call print_char
to:main::@12
main::@12: scope:[main] from main::@11
[33] main::$24 = < main::dw2#10
[34] print_uchar::b#4 = > main::$24
[35] call print_uchar
[31] print_uchar::b#4 = > main::dw2#10
[32] call print_uchar
to:main::@13
main::@13: scope:[main] from main::@12
[36] phi()
[37] call print_char
[33] phi()
[34] call print_char
to:main::@14
main::@14: scope:[main] from main::@13
[38] main::$28 = < main::dw2#10
[39] print_uchar::b#5 = < main::$28
[40] call print_uchar
[35] print_uchar::b#5 = < main::dw2#10
[36] call print_uchar
to:main::@15
main::@15: scope:[main] from main::@14
[41] phi()
[42] call print_ln
[37] phi()
[38] call print_ln
to:main::@16
main::@16: scope:[main] from main::@15
[43] main::dw#1 = ++ main::dw#10
[44] print_line_cursor#39 = print_line_cursor#0
[39] main::dw#1 = ++ main::dw#10
[40] print_line_cursor#39 = print_line_cursor#0
to:main::@1
void print_cls()
print_cls: scope:[print_cls] from main
[45] phi()
[46] call memset
[41] phi()
[42] call memset
to:print_cls::@return
print_cls::@return: scope:[print_cls] from print_cls
[47] return
[43] return
to:@return
void print_ulong(dword print_ulong::dw)
print_ulong: scope:[print_ulong] from main::@2
[48] print_uint::w#0 = > print_ulong::dw#0
[49] print_char_cursor#76 = print_char_cursor#30
[50] call print_uint
[44] print_uint::w#0 = > print_ulong::dw#0
[45] print_char_cursor#76 = print_char_cursor#30
[46] call print_uint
to:print_ulong::@1
print_ulong::@1: scope:[print_ulong] from print_ulong
[51] print_uint::w#1 = < print_ulong::dw#0
[52] call print_uint
[47] print_uint::w#1 = < print_ulong::dw#0
[48] call print_uint
to:print_ulong::@return
print_ulong::@return: scope:[print_ulong] from print_ulong::@1
[53] return
[49] return
to:@return
void print_char(byte print_char::ch)
print_char: scope:[print_char] from main::@11 main::@13 main::@3 main::@5 main::@7 main::@9 print_uchar print_uchar::@1
[54] print_char_cursor#45 = phi( main::@9/print_char_cursor#11, main::@11/print_char_cursor#11, main::@13/print_char_cursor#11, main::@3/print_char_cursor#11, main::@5/print_char_cursor#11, main::@7/print_char_cursor#11, print_uchar/print_char_cursor#69, print_uchar::@1/print_char_cursor#11 )
[54] print_char::ch#8 = phi( main::@9/' ', main::@11/' ', main::@13/' ', main::@3/' ', main::@5/' ', main::@7/' ', print_uchar/print_char::ch#0, print_uchar::@1/print_char::ch#1 )
[55] *print_char_cursor#45 = print_char::ch#8
[56] print_char_cursor#11 = ++ print_char_cursor#45
[50] print_char_cursor#45 = phi( main::@9/print_char_cursor#11, main::@11/print_char_cursor#11, main::@13/print_char_cursor#11, main::@3/print_char_cursor#11, main::@5/print_char_cursor#11, main::@7/print_char_cursor#11, print_uchar/print_char_cursor#69, print_uchar::@1/print_char_cursor#11 )
[50] print_char::ch#8 = phi( main::@9/' ', main::@11/' ', main::@13/' ', main::@3/' ', main::@5/' ', main::@7/' ', print_uchar/print_char::ch#0, print_uchar::@1/print_char::ch#1 )
[51] *print_char_cursor#45 = print_char::ch#8
[52] print_char_cursor#11 = ++ print_char_cursor#45
to:print_char::@return
print_char::@return: scope:[print_char] from print_char
[57] return
[53] return
to:@return
void print_uint(word print_uint::w)
print_uint: scope:[print_uint] from main::@4 main::@6 print_ulong print_ulong::@1
[58] print_char_cursor#67 = phi( main::@4/print_char_cursor#11, main::@6/print_char_cursor#11, print_ulong/print_char_cursor#76, print_ulong::@1/print_char_cursor#11 )
[58] print_uint::w#4 = phi( main::@4/print_uint::w#2, main::@6/print_uint::w#3, print_ulong/print_uint::w#0, print_ulong::@1/print_uint::w#1 )
[59] print_uchar::b#0 = > print_uint::w#4
[60] call print_uchar
[54] print_char_cursor#67 = phi( main::@4/print_char_cursor#11, main::@6/print_char_cursor#11, print_ulong/print_char_cursor#76, print_ulong::@1/print_char_cursor#11 )
[54] print_uint::w#4 = phi( main::@4/print_uint::w#2, main::@6/print_uint::w#3, print_ulong/print_uint::w#0, print_ulong::@1/print_uint::w#1 )
[55] print_uchar::b#0 = > print_uint::w#4
[56] call print_uchar
to:print_uint::@1
print_uint::@1: scope:[print_uint] from print_uint
[61] print_uchar::b#1 = < print_uint::w#4
[62] call print_uchar
[57] print_uchar::b#1 = < print_uint::w#4
[58] call print_uchar
to:print_uint::@return
print_uint::@return: scope:[print_uint] from print_uint::@1
[63] return
[59] return
to:@return
void print_uchar(byte print_uchar::b)
print_uchar: scope:[print_uchar] from main::@10 main::@12 main::@14 main::@8 print_uint print_uint::@1
[64] print_char_cursor#69 = phi( main::@10/print_char_cursor#11, main::@12/print_char_cursor#11, main::@14/print_char_cursor#11, main::@8/print_char_cursor#11, print_uint/print_char_cursor#67, print_uint::@1/print_char_cursor#11 )
[64] print_uchar::b#6 = phi( main::@10/print_uchar::b#3, main::@12/print_uchar::b#4, main::@14/print_uchar::b#5, main::@8/print_uchar::b#2, print_uint/print_uchar::b#0, print_uint::@1/print_uchar::b#1 )
[65] print_uchar::$0 = print_uchar::b#6 >> 4
[66] print_char::ch#0 = print_hextab[print_uchar::$0]
[67] call print_char
[60] print_char_cursor#69 = phi( main::@10/print_char_cursor#11, main::@12/print_char_cursor#11, main::@14/print_char_cursor#11, main::@8/print_char_cursor#11, print_uint/print_char_cursor#67, print_uint::@1/print_char_cursor#11 )
[60] print_uchar::b#6 = phi( main::@10/print_uchar::b#3, main::@12/print_uchar::b#4, main::@14/print_uchar::b#5, main::@8/print_uchar::b#2, print_uint/print_uchar::b#0, print_uint::@1/print_uchar::b#1 )
[61] print_uchar::$0 = print_uchar::b#6 >> 4
[62] print_char::ch#0 = print_hextab[print_uchar::$0]
[63] call print_char
to:print_uchar::@1
print_uchar::@1: scope:[print_uchar] from print_uchar
[68] print_uchar::$2 = print_uchar::b#6 & $f
[69] print_char::ch#1 = print_hextab[print_uchar::$2]
[70] call print_char
[64] print_uchar::$2 = print_uchar::b#6 & $f
[65] print_char::ch#1 = print_hextab[print_uchar::$2]
[66] call print_char
to:print_uchar::@return
print_uchar::@return: scope:[print_uchar] from print_uchar::@1
[71] return
[67] return
to:@return
void print_ln()
print_ln: scope:[print_ln] from main::@15
[72] phi()
[68] phi()
to:print_ln::@1
print_ln::@1: scope:[print_ln] from print_ln print_ln::@2
[73] print_line_cursor#10 = phi( print_ln/print_line_cursor#16, print_ln::@2/print_line_cursor#38 )
[74] print_line_cursor#0 = print_line_cursor#10 + $28
[75] if(print_line_cursor#0<print_char_cursor#11) goto print_ln::@2
[69] print_line_cursor#10 = phi( print_ln/print_line_cursor#16, print_ln::@2/print_line_cursor#38 )
[70] print_line_cursor#0 = print_line_cursor#10 + $28
[71] if(print_line_cursor#0<print_char_cursor#11) goto print_ln::@2
to:print_ln::@return
print_ln::@return: scope:[print_ln] from print_ln::@1
[76] return
[72] return
to:@return
print_ln::@2: scope:[print_ln] from print_ln::@1
[77] print_line_cursor#38 = print_line_cursor#0
[73] print_line_cursor#38 = print_line_cursor#0
to:print_ln::@1
void* memset(void* memset::str , byte memset::c , word memset::num)
memset: scope:[memset] from print_cls
[78] phi()
[74] phi()
to:memset::@1
memset::@1: scope:[memset] from memset memset::@2
[79] memset::dst#2 = phi( memset/(byte*)memset::str#0, memset::@2/memset::dst#1 )
[80] if(memset::dst#2!=memset::end#0) goto memset::@2
[75] memset::dst#2 = phi( memset/(byte*)memset::str#0, memset::@2/memset::dst#1 )
[76] if(memset::dst#2!=memset::end#0) goto memset::@2
to:memset::@return
memset::@return: scope:[memset] from memset::@1
[81] return
[77] return
to:@return
memset::@2: scope:[memset] from memset::@1
[82] *memset::dst#2 = memset::c#0
[83] memset::dst#1 = ++ memset::dst#2
[78] *memset::dst#2 = memset::c#0
[79] memset::dst#1 = ++ memset::dst#2
to:memset::@1

File diff suppressed because one or more lines are too long

View File

@ -3,26 +3,22 @@ constant byte RADIX::DECIMAL = $a
constant byte RADIX::HEXADECIMAL = $10
constant byte RADIX::OCTAL = 8
void main()
word~ main::$16 zp[2]:16 22.0
word~ main::$20 zp[2]:18 22.0
word~ main::$24 zp[2]:20 22.0
word~ main::$28 zp[2]:22 22.0
word~ main::$3 zp[2]:8 22.0
word~ main::$32 zp[2]:8 22.0
word~ main::$33 zp[2]:14 22.0
word~ main::$6 zp[2]:14 22.0
word~ main::$28 zp[2]:10 22.0
word~ main::$29 zp[2]:16 22.0
word~ main::$3 zp[2]:10 22.0
word~ main::$6 zp[2]:16 22.0
dword main::dw
dword main::dw#1 dw zp[4]:2 11.0
dword main::dw#10 dw zp[4]:2 1.65
dword main::dw#10 dw zp[4]:2 1.8333333333333335
dword main::dw2
dword main::dw2#1 dw2 zp[4]:10 7.333333333333333
dword main::dw2#10 dw2 zp[4]:10 3.142857142857143
dword main::dw2#1 dw2 zp[4]:12 7.333333333333333
dword main::dw2#10 dw2 zp[4]:12 3.52
void* memset(void* memset::str , byte memset::c , word memset::num)
byte memset::c
constant byte memset::c#0 c = ' '
byte* memset::dst
byte* memset::dst#1 dst zp[2]:16 2002.0
byte* memset::dst#2 dst zp[2]:16 1334.6666666666667
byte* memset::dst#1 dst zp[2]:8 2002.0
byte* memset::dst#2 dst zp[2]:8 1334.6666666666667
byte* memset::end
constant byte* memset::end#0 end = (byte*)memset::str#0+memset::num#0
word memset::num
@ -36,18 +32,18 @@ byte print_char::ch#0 reg byte a 20002.0
byte print_char::ch#1 reg byte a 20002.0
byte print_char::ch#8 reg byte a 120003.0
byte* print_char_cursor
byte* print_char_cursor#11 print_char_cursor zp[2]:14 2424.739999999999
byte* print_char_cursor#30 print_char_cursor_1 zp[2]:16 11.2
byte* print_char_cursor#45 print_char_cursor zp[2]:14 110035.0
byte* print_char_cursor#67 print_char_cursor zp[2]:14 612.5
byte* print_char_cursor#69 print_char_cursor zp[2]:14 4015.6666666666656
byte* print_char_cursor#76 print_char_cursor zp[2]:14 202.0
byte* print_char_cursor#11 print_char_cursor zp[2]:16 2635.5869565217386
byte* print_char_cursor#30 print_char_cursor_1 zp[2]:8 11.2
byte* print_char_cursor#45 print_char_cursor zp[2]:16 110035.0
byte* print_char_cursor#67 print_char_cursor zp[2]:16 612.5
byte* print_char_cursor#69 print_char_cursor zp[2]:16 4015.6666666666656
byte* print_char_cursor#76 print_char_cursor zp[2]:16 202.0
void print_cls()
constant const byte* print_hextab[] = "0123456789abcdef"z
byte* print_line_cursor
byte* print_line_cursor#0 print_line_cursor zp[2]:16 5004.166666666666
byte* print_line_cursor#0 print_line_cursor zp[2]:8 5004.166666666666
byte* print_line_cursor#10 print_line_cursor_1 zp[2]:6 20103.0
byte* print_line_cursor#16 print_line_cursor_1 zp[2]:6 2.8
byte* print_line_cursor#16 print_line_cursor_1 zp[2]:6 3.1111111111111107
byte* print_line_cursor#38 print_line_cursor_1 zp[2]:6 20002.0
byte* print_line_cursor#39 print_line_cursor_1 zp[2]:6 22.0
void print_ln()
@ -66,25 +62,22 @@ byte print_uchar::b#5 reg byte x 22.0
byte print_uchar::b#6 reg byte x 5512.0
void print_uint(word print_uint::w)
word print_uint::w
word print_uint::w#0 w zp[2]:8 101.0
word print_uint::w#1 w zp[2]:8 202.0
word print_uint::w#2 w zp[2]:8 22.0
word print_uint::w#3 w zp[2]:8 22.0
word print_uint::w#4 w zp[2]:8 742.0
word print_uint::w#0 w zp[2]:10 101.0
word print_uint::w#1 w zp[2]:10 202.0
word print_uint::w#2 w zp[2]:10 22.0
word print_uint::w#3 w zp[2]:10 22.0
word print_uint::w#4 w zp[2]:10 742.0
void print_ulong(dword print_ulong::dw)
dword print_ulong::dw
dword print_ulong::dw#0 dw zp[4]:10 53.25
dword print_ulong::dw#0 dw zp[4]:12 53.25
zp[4]:2 [ main::dw#10 main::dw#1 ]
reg byte a [ print_char::ch#8 print_char::ch#0 print_char::ch#1 ]
reg byte x [ print_uchar::b#6 print_uchar::b#3 print_uchar::b#4 print_uchar::b#5 print_uchar::b#2 print_uchar::b#0 print_uchar::b#1 ]
zp[2]:6 [ print_line_cursor#10 print_line_cursor#16 print_line_cursor#39 print_line_cursor#38 ]
zp[2]:8 [ main::$3 main::$32 print_uint::w#4 print_uint::w#2 print_uint::w#3 print_uint::w#0 print_uint::w#1 ]
zp[4]:10 [ main::dw2#1 main::dw2#10 print_ulong::dw#0 ]
zp[2]:14 [ main::$6 main::$33 print_char_cursor#67 print_char_cursor#45 print_char_cursor#11 print_char_cursor#69 print_char_cursor#76 ]
zp[2]:16 [ main::$16 memset::dst#2 memset::dst#1 print_char_cursor#30 print_line_cursor#0 ]
zp[2]:18 [ main::$20 ]
zp[2]:20 [ main::$24 ]
zp[2]:22 [ main::$28 ]
zp[2]:8 [ memset::dst#2 memset::dst#1 print_char_cursor#30 print_line_cursor#0 ]
zp[2]:10 [ main::$3 main::$28 print_uint::w#4 print_uint::w#2 print_uint::w#3 print_uint::w#0 print_uint::w#1 ]
zp[4]:12 [ main::dw2#1 main::dw2#10 print_ulong::dw#0 ]
zp[2]:16 [ main::$6 main::$29 print_char_cursor#67 print_char_cursor#45 print_char_cursor#11 print_char_cursor#69 print_char_cursor#76 ]
reg byte a [ print_uchar::$0 ]
reg byte x [ print_uchar::$2 ]