1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-23 13:31:12 +00:00

Merged 372-varcall into master.

This commit is contained in:
jespergravgaard 2020-12-06 00:48:41 +01:00
commit abb946cca8
105 changed files with 54196 additions and 1925 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
//FRAGMENT _deref_pbuc1=vbuc2
lda #{c2}
sta {c1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}

View File

@ -0,0 +1,8 @@
lda #<{c2}
sta {c1}
lda #>{c2}
sta {c1}+1
lda #<{c2}>>$10
sta {c1}+2
lda #>{c2}>>$10
sta {c1}+3

View File

@ -0,0 +1,8 @@
lda {m1}
sta {c1}
lda {m1}+1
sta {c1}+1
lda {m1}+2
sta {c1}+2
lda {m1}+3
sta {c1}+3

View File

@ -0,0 +1,8 @@
lda {c1}
sta {m1}
lda {c1}+1
sta {m1}+1
lda {c1}+2
sta {m1}+2
lda {c1}+3
sta {m1}+3

View File

@ -0,0 +1,9 @@
ldy #0
clc
lda ({z2}),y
adc {m3}
sta {m1}
iny
lda ({z2}),y
adc {m3}+1
sta {m1}+1

View File

@ -0,0 +1,9 @@
ldy #0
clc
lda {m2}
adc ({z3}),y
sta {m1}
iny
lda {m2}+1
adc ({z3}),y
sta {m1}+1

View File

@ -0,0 +1,11 @@
ldy #0
clc
lda ({z1}),y
adc {m2}
pha
iny
lda ({z1}),y
adc {m2}+1
sta {z1}+1
pla
sta {z1}

View File

@ -6,7 +6,6 @@ pha
iny
lda ({z1}),y
adc ({z2}),y
sta ({z1}),y
dey
sta {z1}+1
pla
sta ({z1}),y
sta {z1}

View File

@ -251,6 +251,8 @@ public class Compiler {
new Pass1AssertNoLValueIntermediate(program).execute();
new PassNAddTypeConversionAssignment(program, true).execute();
new Pass1AssertProcedureCallParameters(program).execute();
new Pass1ModifiedVarsAnalysis(program).execute();
new Pass1CallStackVarPrepare(program).execute();
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("CONTROL FLOW GRAPH BEFORE SIZEOF FIX");
@ -262,7 +264,7 @@ public class Compiler {
new PassNAssertTypeMatch(program).check();
new Pass1PrepareUnwindStruct(program).execute();
new Pass1UnwindStructPrepare(program).execute();
new Pass1UnwindStructVariables(program).execute();
new Pass1UnwindStructValues(program).execute();
@ -310,10 +312,18 @@ public class Compiler {
}
new Pass1CallVoidReturns(program).execute();
new Pass1CallStackVarConvert(program).execute();
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("PROCEDURE CALLS");
getLog().append(program.getGraph().toString(program));
}
new Pass1CallStack(program).execute();
new Pass1CallVar(program).execute();
new Pass1CallPhiParameters(program).execute();
//getLog().append("PROCEDURE PARAMETERS");
//getLog().append(program.getGraph().toString(program));
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("PROCEDURE PARAMETERS");
getLog().append(program.getGraph().toString(program));
}
new PassNUnwindLValueLists(program).execute();
new Pass1GenerateSingleStaticAssignmentForm(program).execute();
new Pass1CallPhiReturn(program).execute();

View File

@ -151,7 +151,7 @@ public class ControlFlowGraph implements Serializable {
public List<ControlFlowBlock> getEntryPointBlocks(Program program) {
List<ControlFlowBlock> entryPointBlocks = new ArrayList<>();
for(Procedure procedure : program.getScope().getAllProcedures(true)) {
if(ProcedureUtils.isEntrypoint(procedure.getRef(), program) || Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
if(ProcedureUtils.isEntrypoint(procedure.getRef(), program) || Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention()) || Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
// Address-of is used on the procedure
Label procedureLabel = procedure.getLabel();
ControlFlowBlock procedureBlock = getBlock(procedureLabel.getRef());

View File

@ -5,124 +5,155 @@ import dk.camelot64.kickc.model.symbols.Procedure;
import java.util.List;
/** A declaration directive. */
public interface Directive {
public class Directive {
private String name;
public Directive(String name) {
this.name = name;
}
public String getName() {
return name;
}
/** Variable declared const */
class Const implements Directive {
public static class Const extends Directive {
public Const() { super("const"); }
}
/** Variable declared volatile */
class Volatile implements Directive {
public static class Volatile extends Directive {
public Volatile() { super("volatile"); }
}
/** Variable declared register. */
class Register implements Directive {
public static class Register extends Directive {
public Register() { super("register"); }
}
/** Variable declared static. */
class Static implements Directive {
public static class Static extends Directive {
public Static() { super("static"); }
}
/** Function declared inline. */
class Inline implements Directive {
static public class Inline extends Directive {
public Inline() { super("inline"); }
}
/** Function declared intrinsic. */
class Intrinsic implements Directive {
public static class Intrinsic extends Directive {
public Intrinsic() { super("intrinsic"); }
}
/** Variable declared as extern. */
class Extern implements Directive {
public static class Extern extends Directive {
public Extern() { super("extern"); }
}
/** Variable declared as export. */
class Export implements Directive {
public static class Export extends Directive {
public Export() { super("export"); }
}
/** Variable declared as pointer to volatile ( volatile * ) */
class ToVolatile implements Directive {
public static class ToVolatile extends Directive {
public ToVolatile() { super("volatile*"); }
}
/** Variable declared as pointer to const ( const * ) */
class ToConst implements Directive {
public static class ToConst extends Directive {
public ToConst() { super("const*"); }
}
/** Variable __ssa */
class FormSsa implements Directive {
public static class FormSsa extends Directive {
public FormSsa() { super("__ssa"); }
}
/** Variable __ma */
class FormMa implements Directive {
public static class FormMa extends Directive {
public FormMa() { super("__ma"); }
}
/** Variable __zp */
class MemZp implements Directive {
public static class MemZp extends Directive {
public MemZp() { super("__zp"); }
}
/** Variable __mem */
class MemMain implements Directive {
public static class MemMain extends Directive {
public MemMain() { super("__mem"); }
}
/** Function with specific declared calling convention. */
class CallingConvention implements Directive {
public static class CallingConvention extends Directive {
public Procedure.CallingConvention callingConvention;
public CallingConvention(Procedure.CallingConvention callingConvention) {
super(callingConvention.getName());
this.callingConvention = callingConvention;
}
}
/** Function declared interrupt. */
class Interrupt implements Directive {
public static class Interrupt extends Directive {
public Procedure.InterruptType interruptType;
public Interrupt(Procedure.InterruptType interruptType) {
super(interruptType.name());
this.interruptType = interruptType;
}
}
/** Variable memory alignment. */
class Align implements Directive {
public static class Align extends Directive {
int alignment;
public Align(int alignment) {
super("__align");
this.alignment = alignment;
}
}
/** Variable hardcoded register directive. */
class NamedRegister implements Directive {
public static class NamedRegister extends Directive {
/** Name of register to use for the variable (if named) */
public String name;
public NamedRegister(String name) {
super("__register");
this.name = name;
}
}
/** Variable hardcoded __address() directive */
class Address implements Directive {
public static class Address extends Directive {
/** Optional hard-coded address to use for storing the variable. */
public Long address;
public Address(Long address) {
super("__address");
this.address = address;
}
}
/** Reservation of zero-page addresses */
class ReserveZp implements Directive {
public static class ReserveZp extends Directive {
public List<Integer> reservedZp;
public ReserveZp(List<Integer> reservedZp) {
super("__reserve_zp");
this.reservedZp = reservedZp;
}
}

View File

@ -39,6 +39,24 @@ public class StructVariableMemberUnwinding {
return structVariables.get(ref);
}
/**
* Look through all unwound variables and find the master struct variable that was unwound.
* @param unwoundMemberRef Variable reference of unwound member
* @return The master variable reference. null if the passed member is not unwound.
*/
public SymbolVariableRef getUnwindingMaster(SymbolVariableRef unwoundMemberRef) {
for(SymbolVariableRef masterVar : structVariables.keySet()) {
final VariableUnwinding masterVarUnwinding = getVariableUnwinding(masterVar);
for(String memberName : masterVarUnwinding.getMemberNames()) {
final SymbolVariableRef memberUnwound = masterVarUnwinding.getMemberUnwound(memberName);
if(memberUnwound.equals(unwoundMemberRef))
return masterVar;
}
}
return null;
}
/** Information about how a single struct variable was unwound. */
public static class VariableUnwinding {

View File

@ -1,6 +1,5 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.model.statements.StatementSource;
import java.util.*;

View File

@ -40,10 +40,12 @@ public class Procedure extends Scope {
/** The method for passing parameters and return value to the procedure. */
public enum CallingConvention {
/** Parameters and return value handled through call PHI-transitions. */
/** Parameters and return value handled through PHI-transitions. */
PHI_CALL("__phicall"),
/** Parameters and return value over the stack. */
STACK_CALL("__stackcall");
STACK_CALL("__stackcall"),
/** Parameters and return value handled through variables. */
VAR_CALL("__varcall");
private final String name;

View File

@ -29,4 +29,8 @@ public class ParamValue implements RValue {
return "param("+parameter.toString(program)+")";
}
@Override
public String toString() {
return toString(null);
}
}

View File

@ -78,7 +78,7 @@ ADDRESS_MAINMEM: '__mem' ;
FORM_SSA: '__ssa' ;
FORM_MA: '__ma' ;
INTRINSIC: '__intrinsic' ;
CALLINGCONVENTION: '__stackcall' | '__phicall' ;
CALLINGCONVENTION: '__stackcall' | '__phicall' | '__varcall' ;
IF: 'if' ;
ELSE: 'else' ;
WHILE: 'while' ;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -390,13 +390,15 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Procedure procedure = new Procedure(name, type, program.getScope(), currentCodeSegment, currentDataSegment, currentCallingConvention);
addDirectives(procedure, directives, StatementSource.procedureDecl(ctx));
procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx)));
varDecl.exitType();
scopeStack.push(procedure);
Variable returnVar = null;
if(!SymbolType.VOID.equals(type)) {
returnVar = procedure.add(Variable.createPhiMaster("return", type, procedure, defaultMemoryArea, procedure.getSegmentData()));
final VariableBuilder builder = new VariableBuilder("return", procedure, false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
returnVar = builder.build();
}
varDecl.exitType();
List<Variable> parameterList = new ArrayList<>();
if(ctx.parameterListDecl() != null) {
parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
@ -1169,8 +1171,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
procedure.setReservedZps(((Directive.ReserveZp) directive).reservedZp);
} else if(directive instanceof Directive.Intrinsic) {
procedure.setDeclaredIntrinsic(true);
} else {
throw new CompileError("Unsupported function directive " + directive, source);
//} else {
// throw new CompileError("Unsupported function directive " + directive.getName(), source);
}
}
}
@ -1189,7 +1191,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(directive instanceof Directive.Inline) {
conditional.setDeclaredUnroll(true);
} else {
throw new CompileError("Unsupported loop directive " + directive, source);
throw new CompileError("Unsupported loop directive " + directive.getName(), source);
}
}
}

View File

@ -101,7 +101,11 @@ public class Pass1CallPhiParameters {
for(int i = 0; i < parameterDefs.size(); i++) {
Variable parameterDecl = parameterDefs.get(i);
RValue parameterValue = parameterValues.get(i);
stmtIt.add(new StatementAssignment((LValue) parameterDecl.getRef(), parameterValue, true, call.getSource(), Comment.NO_COMMENTS));
final StatementAssignment assignment = new StatementAssignment((LValue) parameterDecl.getRef(), parameterValue, true, call.getSource(), Comment.NO_COMMENTS);
stmtIt.add(assignment);
if(parameterDecl.isStruct()) {
Pass1UnwindStructValues.unwindAssignment(assignment, stmtIt, block, program);
}
}
stmtIt.next();
}

View File

@ -19,7 +19,7 @@ import dk.camelot64.kickc.passes.utils.SizeOfConstants;
import java.util.*;
/** Handle calling convention {@link Procedure.CallingConvention#STACK_CALL} by converting the making control flow graph and symbols calling convention specific. */
/** Handle calling convention {@link Procedure.CallingConvention#STACK_CALL} by converting parameter passing / return values to stack operations. */
public class Pass1CallStack extends Pass2SsaOptimization {
public Pass1CallStack(Program program) {
@ -53,41 +53,6 @@ public class Pass1CallStack extends Pass2SsaOptimization {
if(createStackBase)
CallingConventionStack.getStackBaseConstant(getScope());
// Set variables modified in STACK_CALL procedures to load/store
for(Procedure procedure : getScope().getAllProcedures(true)) {
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
Set<VariableRef> modifiedVars = getProgram().getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for(VariableRef modifiedVar : modifiedVars) {
final Variable variable = getScope().getVariable(modifiedVar);
if(variable.isKindPhiMaster()) {
getLog().append("Converting PHI-variable modified inside __stackcall procedure "+procedure.getFullName()+"() to load/store "+variable.toString(getProgram()));
variable.setKind(Variable.Kind.LOAD_STORE);
}
}
}
}
// Transform STACK_CALL calls to call-prepare, call-execute, call-finalize
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
ProcedureRef procedureRef = call.getProcedure();
Procedure procedure = getScope().getProcedure(procedureRef);
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
boolean hasPrepare = (call.getParameters().size() > 0) || !SymbolType.VOID.equals(procedure.getReturnType());
stmtIt.remove();
stmtIt.add(new StatementCallPrepare(procedureRef, call.getParameters(), call.getSource(), hasPrepare?call.getComments():Comment.NO_COMMENTS));
stmtIt.add(new StatementCallExecute(procedureRef, call.getSource(), hasPrepare?Comment.NO_COMMENTS:call.getComments()));
stmtIt.add(new StatementCallFinalize(call.getlValue(), procedureRef, call.getSource(), Comment.NO_COMMENTS));
getLog().append("Calling convention " + Procedure.CallingConvention.STACK_CALL + " adding prepare/execute/finalize for " + call.toString(getProgram(), false));
}
}
}
}
// Convert param(xxx) to stackidx(PARAM_X) = xxx
if(offsetConstants.size() > 0) {
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
@ -206,7 +171,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
* @param stackReturnOffset The offset onto the stack to place the value at
* @param source The source line
* @param comments The comments
* @param stmtIt The statment iterator used to add statements to.
* @param stmtIt The statement iterator used to add statements to.
*/
private void generateStackReturnValues(RValue value, SymbolType returnType, ConstantValue stackReturnOffset, StatementSource source, List<Comment> comments, ListIterator<Statement> stmtIt) {
if(!(value instanceof ValueList) || !(returnType instanceof SymbolTypeStruct)) {

View File

@ -0,0 +1,48 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ProcedureRef;
import java.util.ListIterator;
/** Handle calling conventions {@link Procedure.CallingConvention#STACK_CALL} {@link Procedure.CallingConvention#VAR_CALL} by converting to call-prepare, call-execute, call-finalize */
public class Pass1CallStackVarConvert extends Pass2SsaOptimization {
public Pass1CallStackVarConvert(Program program) {
super(program);
}
@Override
public boolean step() {
// Transform STACK_CALL/VAR_CALL calls to call-prepare, call-execute, call-finalize
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
ProcedureRef procedureRef = call.getProcedure();
Procedure procedure = getScope().getProcedure(procedureRef);
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention()) || Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
boolean hasPrepare = (call.getParameters().size() > 0) || !SymbolType.VOID.equals(procedure.getReturnType());
stmtIt.remove();
stmtIt.add(new StatementCallPrepare(procedureRef, call.getParameters(), call.getSource(), hasPrepare?call.getComments():Comment.NO_COMMENTS));
stmtIt.add(new StatementCallExecute(procedureRef, call.getSource(), hasPrepare?Comment.NO_COMMENTS:call.getComments()));
stmtIt.add(new StatementCallFinalize(call.getlValue(), procedureRef, call.getSource(), Comment.NO_COMMENTS));
getLog().append("Calling convention " + procedure.getCallingConvention().getName() + " adding prepare/execute/finalize for " + call.toString(getProgram(), false));
}
}
}
}
return false;
}
}

View File

@ -0,0 +1,54 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.Set;
/** Handle calling conventions {@link Procedure.CallingConvention#STACK_CALL} {@link Procedure.CallingConvention#VAR_CALL} by converting to call-prepare, call-execute, call-finalize */
public class Pass1CallStackVarPrepare extends Pass2SsaOptimization {
public Pass1CallStackVarPrepare(Program program) {
super(program);
}
@Override
public boolean step() {
// Set variables modified in STACK_CALL/VAR_CALL procedures to load/store
for(Procedure procedure : getScope().getAllProcedures(true)) {
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention()) || Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
Set<VariableRef> modifiedVars = getProgram().getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for(VariableRef modifiedVar : modifiedVars) {
final Variable variable = getScope().getVariable(modifiedVar);
if(variable.isKindPhiMaster()) {
getLog().append("Converting variable modified inside "+procedure.getCallingConvention().getName()+" procedure "+procedure.getFullName()+"() to load/store "+variable.toString(getProgram()));
variable.setKind(Variable.Kind.LOAD_STORE);
}
}
}
}
// Set all parameter/return variables in VAR_CALL procedures to LOAD/STORE
for(Procedure procedure : getScope().getAllProcedures(true)) {
if(Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
for(Variable parameter : procedure.getParameters()) {
parameter.setKind(Variable.Kind.LOAD_STORE);
getLog().append("Converting parameter in "+procedure.getCallingConvention().getName()+" procedure to load/store "+parameter.toString(getProgram()));
}
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
Variable returnVar = procedure.getLocalVariable("return");
returnVar.setKind(Variable.Kind.LOAD_STORE);
getLog().append("Converting return in "+procedure.getCallingConvention().getName()+" procedure to load/store "+returnVar.toString(getProgram()));
}
}
}
return false;
}
}

View File

@ -0,0 +1,135 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.CastValue;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.ValueList;
import dk.camelot64.kickc.passes.unwinding.ValueSource;
import dk.camelot64.kickc.passes.unwinding.ValueSourceFactory;
import java.util.List;
import java.util.ListIterator;
/** Handle calling convention {@link Procedure.CallingConvention#VAR_CALL } by converting the making control flow graph and symbols calling convention specific. */
public class Pass1CallVar extends Pass2SsaOptimization {
public Pass1CallVar(Program program) {
super(program);
}
@Override
public boolean step() {
// Convert procedure return xxx to proc.return = xxx;
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementReturn) {
final Scope blockScope = getScope().getScope(block.getScope());
if(blockScope instanceof Procedure) {
Procedure procedure = (Procedure) blockScope;
final SymbolType returnType = procedure.getReturnType();
if(!SymbolType.VOID.equals(returnType) && Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
final RValue value = ((StatementReturn) statement).getValue();
((StatementReturn) statement).setValue(null);
}
}
}
}
}
// Convert xxx = callfinalize to xxx = proc.return
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementCallFinalize) {
final StatementCallFinalize call = (StatementCallFinalize) statement;
Procedure procedure = getScope().getProcedure(call.getProcedure());
final SymbolType returnType = procedure.getReturnType();
if(Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
final StatementSource source = call.getSource();
final List<Comment> comments = call.getComments();
final LValue lValue = call.getlValue();
if(lValue!=null) {
Variable returnVar = procedure.getLocalVariable("return");
stmtIt.previous();
generateCallFinalize(lValue, returnVar, source, comments, stmtIt, statement);
stmtIt.next();
}
stmtIt.remove();
}
}
}
}
// Convert callprepare(xxx,yyy,) to proc.param = xxx, ...;
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementCallPrepare) {
final StatementCallPrepare call = (StatementCallPrepare) statement;
Procedure procedure = getScope().getProcedure(call.getProcedure());
if(Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
stmtIt.previous();
final StatementSource source = call.getSource();
List<Comment> comments = call.getComments();
final List<Variable> parameterDefs = procedure.getParameters();
for(int i = 0; i < parameterDefs.size(); i++) {
final RValue parameterVal = call.getParameters().get(i);
final Variable parameterDef = parameterDefs.get(i);
stmtIt.add(new StatementAssignment(parameterDef.getVariableRef(), parameterVal, false, source, comments));
comments = Comment.NO_COMMENTS;
}
stmtIt.next();
stmtIt.remove();
}
}
}
}
return false;
}
private void generateCallFinalize(LValue lValue, Variable returnVar, StatementSource source, List<Comment> comments, ListIterator<Statement> stmtIt, Statement currentStmt) {
final SymbolType returnType = returnVar.getType();
if(!(lValue instanceof ValueList) || !(returnType instanceof SymbolTypeStruct)) {
// A simple value - add simple assignment
final StatementAssignment stackPull = new StatementAssignment(lValue, returnVar.getRef(), false, source, comments);
stmtIt.add(stackPull);
getLog().append("Calling convention " + Procedure.CallingConvention.VAR_CALL + " adding return value assignment " + stackPull);
} else {
final CastValue structLValue = new CastValue(returnType, lValue);
// A struct to unwind
final ValueSource lValueSource = ValueSourceFactory.getValueSource(structLValue, getProgram(), getScope(), currentStmt, stmtIt, null);
final ValueSource rValueSource = ValueSourceFactory.getValueSource(returnVar.getRef(), getProgram(), getScope(), currentStmt, stmtIt, null);
Pass1UnwindStructValues.copyValues(lValueSource, rValueSource, null, false, currentStmt, null, stmtIt, getProgram());
/*
final List<RValue> memberLValues = ((ValueList) lValue).getList();
final StructVariableMemberUnwinding structVariableMemberUnwinding = getProgram().getStructVariableMemberUnwinding();
final StructVariableMemberUnwinding.VariableUnwinding returnVarUnwinding = structVariableMemberUnwinding.getVariableUnwinding(returnVar.getRef());
for(RValue memberLValue : memberLValues) {
}
for(int i = 0; i < structMemberVars.size(); i++) {
final Variable memberVar = structMemberVars.get(i);
final RValue memberValue = memberLValues.get(i);
generateCallFinalize(memberValue, memberVar.getType(), source, comments, stmtIt);
}
*/
}
}
}

View File

@ -20,9 +20,9 @@ import java.util.List;
* - Constantify all assignment RValues that are structs
* - Add casts to struct parameter values in calls
*/
public class Pass1PrepareUnwindStruct extends Pass2SsaOptimization {
public class Pass1UnwindStructPrepare extends Pass2SsaOptimization {
public Pass1PrepareUnwindStruct(Program program) {
public Pass1UnwindStructPrepare(Program program) {
super(program);
}

View File

@ -50,7 +50,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementAssignment) {
modified |= unwindAssignment((StatementAssignment) statement, stmtIt, block);
modified |= unwindAssignment((StatementAssignment) statement, stmtIt, block, getProgram());
} else if(statement instanceof StatementCall) {
modified |= unwindCall((StatementCall) statement, stmtIt, block);
} else if(statement instanceof StatementReturn) {
@ -90,35 +90,58 @@ public class Pass1UnwindStructValues extends Pass1Base {
* @param call The call to unwind
*/
private boolean unwindCall(StatementCall call, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
final Procedure procedure = getScope().getProcedure(call.getProcedure());
// Unwind struct value return value
boolean lvalUnwound = false;
final ValueSource valueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getScope(), call, stmtIt, currentBlock);
RValue unwoundLValue = unwindValue(valueSource, call, stmtIt, currentBlock);
if(unwoundLValue != null && !call.getlValue().equals(unwoundLValue)) {
call.setlValue((LValue) unwoundLValue);
if(getLog().isVerboseStructUnwind())
getLog().append("Converted procedure call LValue to member unwinding " + call.toString(getProgram(), false));
lvalUnwound = true;
Variable procReturnVar = procedure.getLocalVariable("return");
// TODO: Return-variable has been unwound - detect that instead - use getProgram().getStructVariableMemberUnwinding().getUnwindingMaster() like for parameters
if(procReturnVar != null && procReturnVar.isStructUnwind()) {
if(!(call.getlValue() instanceof ValueList)) {
// Return value already unwound - move on
final ValueSource valueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getScope(), call, stmtIt, currentBlock);
RValue unwoundLValue = unwindValue(valueSource, call, stmtIt, currentBlock);
if(call.getlValue().equals(unwoundLValue))
throw new CompileError("Call return value already unwound", call);
if(unwoundLValue == null)
throw new CompileError("Cannot unwind call return value", call);
call.setlValue((LValue) unwoundLValue);
if(getLog().isVerboseStructUnwind())
getLog().append("Converted procedure call LValue to member unwinding " + call.toString(getProgram(), false));
lvalUnwound = true;
}
}
// Unwind any struct value parameters
ArrayList<RValue> unwoundParameters = new ArrayList<>();
boolean anyParameterUnwound = false;
for(RValue parameter : call.getParameters()) {
final List<Variable> procParameters = procedure.getParameters();
final List<RValue> callParameters = call.getParameters();
for(int idx_call = 0, idx_proc = 0; idx_call < callParameters.size(); idx_call++) {
final RValue callParameter = callParameters.get(idx_call);
final Variable procParameter = procParameters.get(idx_proc);
boolean unwound = false;
final ValueSource parameterSource = ValueSourceFactory.getValueSource(parameter, getProgram(), getScope(), call, stmtIt, currentBlock);
if(parameterSource != null && parameterSource.isUnwindable()) {
// Passing a struct variable - convert it to member variables
for(String memberName : parameterSource.getMemberNames(getScope())) {
ValueSource memberUnwinding = parameterSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, stmtIt, currentBlock);
unwoundParameters.add(memberUnwinding.getSimpleValue(getScope()));
}
unwound = true;
anyParameterUnwound = true;
final SymbolVariableRef unwindingMaster = getProgram().getStructVariableMemberUnwinding().getUnwindingMaster(procParameter.getRef());
if(unwindingMaster != null) {
// The procedure parameter is unwound
final ValueSource parameterSource = ValueSourceFactory.getValueSource(callParameter, getProgram(), getScope(), call, stmtIt, currentBlock);
if(parameterSource != null && parameterSource.isUnwindable())
// Passing an unwinding struct value
for(String memberName : parameterSource.getMemberNames(getScope())) {
ValueSource memberUnwinding = parameterSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, stmtIt, currentBlock);
unwoundParameters.add(memberUnwinding.getSimpleValue(getScope()));
unwound = true;
anyParameterUnwound = true;
idx_proc++;
}
else
idx_proc++;
} else {
idx_proc++;
}
if(!unwound) {
unwoundParameters.add(parameter);
unwoundParameters.add(callParameter);
}
}
@ -131,7 +154,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
}
/**
* Unwind an LVa.lue to a ValueList if it is unwindable.
* Unwind an LValue to a ValueList if it is unwindable.
*
* @param value The value to unwind
* @param statement The current statement
@ -185,7 +208,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
ArrayList<String> unwoundParameterNames = new ArrayList<>();
boolean procedureUnwound = false;
for(Variable parameter : procedure.getParameters()) {
if(parameter.getType() instanceof SymbolTypeStruct) {
if(parameter.isStructUnwind()) {
StructVariableMemberUnwinding structVariableMemberUnwinding = getProgram().getStructVariableMemberUnwinding();
StructVariableMemberUnwinding.VariableUnwinding parameterUnwinding = structVariableMemberUnwinding.getVariableUnwinding(parameter.getRef());
for(String memberName : parameterUnwinding.getMemberNames()) {
@ -214,9 +237,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
* @param stmtIt The statement iterator used for adding/removing statements
* @param currentBlock The current code block
*/
private boolean unwindAssignment(StatementAssignment assignment, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
public static boolean unwindAssignment(StatementAssignment assignment, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, Program program) {
LValue lValue = assignment.getlValue();
SymbolType lValueType = SymbolTypeInference.inferType(getScope(), lValue);
SymbolType lValueType = SymbolTypeInference.inferType(program.getScope(), lValue);
if(lValueType instanceof SymbolTypeStruct && assignment.getOperator() == null) {
@ -230,10 +253,10 @@ public class Pass1UnwindStructValues extends Pass1Base {
if(rValue instanceof MemcpyValue || rValue instanceof MemsetValue || rValue instanceof StructUnwoundPlaceholder)
return false;
ValueSource lValueSource = ValueSourceFactory.getValueSource(lValue, getProgram(), getScope(), assignment, stmtIt, currentBlock);
ValueSource rValueSource = ValueSourceFactory.getValueSource(rValue, getProgram(), getScope(), assignment, stmtIt, currentBlock);
ValueSource lValueSource = ValueSourceFactory.getValueSource(lValue, program, program.getScope(), assignment, stmtIt, currentBlock);
ValueSource rValueSource = ValueSourceFactory.getValueSource(rValue, program, program.getScope(), assignment, stmtIt, currentBlock);
List<RValue> lValueUnwoundList = new ArrayList<>();
if(copyValues(lValueSource, rValueSource, lValueUnwoundList, initialAssignment, assignment, currentBlock, stmtIt)) {
if(copyValues(lValueSource, rValueSource, lValueUnwoundList, initialAssignment, assignment, currentBlock, stmtIt, program)) {
if(lValue instanceof VariableRef) {
StructUnwoundPlaceholder unwoundPlaceholder = new StructUnwoundPlaceholder(lValueStructType, lValueUnwoundList);
assignment.setrValue2(unwoundPlaceholder);
@ -246,20 +269,20 @@ public class Pass1UnwindStructValues extends Pass1Base {
return false;
}
private boolean copyValues(ValueSource lValueSource, ValueSource rValueSource, List<RValue> lValueUnwoundList, boolean initialAssignment, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator<Statement> stmtIt) {
public static boolean copyValues(ValueSource lValueSource, ValueSource rValueSource, List<RValue> lValueUnwoundList, boolean initialAssignment, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator<Statement> stmtIt, Program program) {
if(lValueSource == null || rValueSource == null)
return false;
if(lValueSource.isSimple() && rValueSource.isSimple()) {
stmtIt.previous();
LValue lValueRef = (LValue) lValueSource.getSimpleValue(getScope());
RValue rValueRef = rValueSource.getSimpleValue(getScope());
LValue lValueRef = (LValue) lValueSource.getSimpleValue(program.getScope());
RValue rValueRef = rValueSource.getSimpleValue(program.getScope());
if(lValueUnwoundList != null)
lValueUnwoundList.add(lValueRef);
Statement copyStmt = new StatementAssignment(lValueRef, rValueRef, initialAssignment, currentStmt.getSource(), Comment.NO_COMMENTS);
stmtIt.add(copyStmt);
stmtIt.next();
if(getLog().isVerboseStructUnwind())
getLog().append("Adding value simple copy " + copyStmt.toString(getProgram(), false));
if(program.getLog().isVerboseStructUnwind())
program.getLog().append("Adding value simple copy " + copyStmt.toString(program, false));
return true;
} else if(lValueSource.isBulkCopyable() && rValueSource.isBulkCopyable()) {
// Use bulk unwinding for a struct member that is an array
@ -267,23 +290,23 @@ public class Pass1UnwindStructValues extends Pass1Base {
if(lValueSource.getArraySpec() != null)
if(rValueSource.getArraySpec() == null || !lValueSource.getArraySpec().equals(rValueSource.getArraySpec()))
throw new RuntimeException("ArraySpec mismatch!");
LValue lValueMemberVarRef = lValueSource.getBulkLValue(getScope());
RValue rValueBulkUnwinding = rValueSource.getBulkRValue(getScope());
LValue lValueMemberVarRef = lValueSource.getBulkLValue(program.getScope());
RValue rValueBulkUnwinding = rValueSource.getBulkRValue(program.getScope());
if(lValueUnwoundList != null)
lValueUnwoundList.add(lValueMemberVarRef);
Statement copyStmt = new StatementAssignment(lValueMemberVarRef, rValueBulkUnwinding, initialAssignment, currentStmt.getSource(), Comment.NO_COMMENTS);
stmtIt.add(copyStmt);
stmtIt.next();
if(getLog().isVerboseStructUnwind())
getLog().append("Adding value bulk copy " + copyStmt.toString(getProgram(), false));
if(program.getLog().isVerboseStructUnwind())
program.getLog().append("Adding value bulk copy " + copyStmt.toString(program, false));
return true;
} else if(lValueSource.isUnwindable() && rValueSource.isUnwindable()) {
if(getLog().isVerboseStructUnwind())
getLog().append("Unwinding value copy " + currentStmt.toString(getProgram(), false));
for(String memberName : lValueSource.getMemberNames(getScope())) {
ValueSource lValueSubSource = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, stmtIt, currentBlock);
ValueSource rValueSubSource = rValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, stmtIt, currentBlock);
boolean success = copyValues(lValueSubSource, rValueSubSource, lValueUnwoundList, initialAssignment, currentStmt, currentBlock, stmtIt);
if(program.getLog().isVerboseStructUnwind())
program.getLog().append("Unwinding value copy " + currentStmt.toString(program, false));
for(String memberName : lValueSource.getMemberNames(program.getScope())) {
ValueSource lValueSubSource = lValueSource.getMemberUnwinding(memberName, program, program.getScope(), currentStmt, stmtIt, currentBlock);
ValueSource rValueSubSource = rValueSource.getMemberUnwinding(memberName, program, program.getScope(), currentStmt, stmtIt, currentBlock);
boolean success = copyValues(lValueSubSource, rValueSubSource, lValueUnwoundList, initialAssignment, currentStmt, currentBlock, stmtIt, program);
if(!success)
throw new InternalError("Error during value unwinding copy! ", currentStmt);
}

View File

@ -28,11 +28,11 @@ public class PassNUnwindLValueLists extends Pass2SsaOptimization {
Statement statement = stmtIt.next();
if(statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
if(assignment.getlValue() instanceof ValueList && assignment.getOperator()==null && assignment.getrValue2() instanceof ValueList) {
if(assignment.getlValue() instanceof ValueList && assignment.getOperator() == null && assignment.getrValue2() instanceof ValueList) {
// Value-list to value list copy - unwind it
ValueList lValueList = (ValueList) assignment.getlValue();
ValueList rValueList = (ValueList) assignment.getrValue2();
if(lValueList.getList().size()!=rValueList.getList().size()) {
if(lValueList.getList().size() != rValueList.getList().size()) {
throw new CompileError("Assignment value lists have different sizes ", statement);
}
stmtIt.remove();
@ -41,7 +41,7 @@ public class PassNUnwindLValueLists extends Pass2SsaOptimization {
RValue rValue = (RValue) rValueList.getList().get(i);
stmtIt.add(new StatementAssignment(lValue, rValue, assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS));
}
getLog().append("Unwinding list assignment "+assignment.toString(getProgram(), false));
getLog().append("Unwinding list assignment " + assignment.toString(getProgram(), false));
modified = true;
}
}

View File

@ -42,12 +42,70 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testAdventOfCode04() throws IOException, URISyntaxException {
compileAndCompare("adventofcode/2020-04.c");
}
@Test
public void testAdventOfCode03() throws IOException, URISyntaxException {
compileAndCompare("adventofcode/2020-03.c");
}
@Test
public void testAdventOfCode02() throws IOException, URISyntaxException {
compileAndCompare("adventofcode/2020-02.c");
}
@Test
public void testAdventOfCode01() throws IOException, URISyntaxException {
compileAndCompare("adventofcode/2020-01.c");
}
// https://gitlab.com/camelot/kickc/-/issues/564
//@Test
//public void testUnknownVarProblem() throws IOException, URISyntaxException {
// compileAndCompare("unknown-var-problem.c", log().verboseParse());
//}
// TODO: Fix functions returning __ma/__ssa structs
//@Test
//public void testStructUnwinding3() throws IOException, URISyntaxException {
// compileAndCompare("struct-unwinding-3.c", log().verboseCreateSsa().verboseCreateSsa());
//}
@Test
public void testStructUnwinding2() throws IOException, URISyntaxException {
compileAndCompare("struct-unwinding-2.c");
}
@Test
public void testStructUnwinding1() throws IOException, URISyntaxException {
compileAndCompare("struct-unwinding-1.c");
}
// TODO: Fix __varcall returning structs
//@Test
//public void testVarCall4() throws IOException, URISyntaxException {
// compileAndCompare("varcall-4.c", log().verboseStructUnwind().verboseCreateSsa());
//}
@Test
public void testVarCall3() throws IOException, URISyntaxException {
compileAndCompare("varcall-3.c");
}
@Test
public void testVarCall2() throws IOException, URISyntaxException {
compileAndCompare("varcall-2.c");
}
@Test
public void testVarCall1() throws IOException, URISyntaxException {
compileAndCompare("varcall-1.c");
}
@Test
public void testConstVolatileProblem1() throws IOException, URISyntaxException {
compileAndCompare("const-volatile-problem.c");

View File

@ -0,0 +1,246 @@
// https://adventofcode.com/2020/day/1/input
// Find 2 entries that give 2020 when added together
// And 3 entries that give 2020 when added together
#pragma target(atarixl)
#include <stdio.h>
#include <conio.h>
#include <multiply.h>
extern unsigned int entries[];
void main() {
unsigned int num_entries = sizeof(entries)/sizeof(unsigned int);
clrscr();
printf("looking a+b=2020 within %u entries\n",num_entries);
for(unsigned int i=0;i<num_entries;i++) {
for(unsigned int j=i+1;j<num_entries;j++) {
if(entries[i]+entries[j]==2020) {
printf("\n");
printf("match found [%u]%u+[%u]%u=2020\n", i,entries[i], j,entries[j]);
unsigned long mul = mul16u(entries[i],entries[j]);
printf("multiplied %lu\n", mul);
}
}
printf(".");
}
printf("\nlooking a+b+c=2020 within %u entries\n",num_entries);
for(unsigned int i=0;i<num_entries;i++) {
for(unsigned int j=i+1;j<num_entries;j++) {
for(unsigned int k=j+1;k<num_entries;k++) {
if(entries[i]+entries[j]+entries[k]==2020) {
printf("\n");
printf("match found [%u]%u+[%u]%u+[%u]%u=2020\n", i,entries[i], j,entries[j], k,entries[k]);
unsigned long mul1 = mul16u(entries[i],entries[k]); // I am cheating a bit here multiplying entry i&k first
unsigned long mul2 = mul16u( <mul1 ,entries[j] ); // Because I knwo the product of those fit in an unsigned int
printf("multiplied %lu\n", mul2);
}
}
}
printf(".");
}
}
unsigned int entries[] = {
1935,
1956,
1991,
1425,
1671,
1537,
1984,
1569,
1873,
1840,
1720,
1937,
1823,
1625,
1727,
1812,
1714,
1900,
1939,
1931,
1951,
1756,
1942,
1611,
1979,
1930,
1996,
2000,
1544,
1780,
1687,
1760,
1836,
1814,
1691,
1817,
1964,
1899,
1577,
1547,
866,
1560,
1988,
1601,
1970,
1738,
1507,
1667,
1851,
1933,
1515,
1856,
1969,
1860,
1801,
2007,
1866,
1800,
1749,
1843,
1711,
1495,
1905,
763,
1672,
1858,
1987,
1492,
1849,
1993,
1737,
1874,
1658,
1810,
1665,
1768,
1950,
1879,
1816,
1868,
1995,
1763,
1783,
1833,
1968,
1847,
1748,
1725,
1891,
1755,
286,
1976,
1977,
1655,
1808,
1986,
1779,
1861,
1953,
1888,
1792,
1811,
1872,
1790,
1839,
1985,
1827,
1842,
1925,
1735,
1635,
1821,
1820,
1973,
1531,
1770,
59,
1846,
1932,
1907,
1730,
933,
1395,
1753,
1751,
361,
1530,
1782,
1087,
1589,
1929,
1795,
1815,
1732,
1765,
1877,
1722,
526,
1709,
1789,
1892,
1913,
1662,
1809,
1670,
1947,
1835,
1587,
1758,
1982,
2009,
1757,
670,
1983,
1524,
1878,
1796,
1952,
566,
1922,
1882,
1870,
1799,
1731,
1724,
1805,
2003,
1596,
1566,
1853,
1911,
1857,
1739,
1744,
1627,
1729,
1745,
1845,
1582,
1884,
1883,
1941,
1764,
1685,
1791,
1837,
1697,
1742,
1781,
1948,
1876,
1989,
1643,
1871,
1906,
1726,
1958,
1502,
1927,
1946
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,366 @@
// https://adventofcode.com/2020/day/3
#pragma target(atarixl)
#include <stdio.h>
#include <conio.h>
#define MAP_WIDTH 31
#define MAP_HEIGHT 323
extern char *map;
void main () {
clrscr();
// Puzzle part 1
printf("1: encountered %u trees\n",test_slope(3,1));
printf("2a: encountered %u trees\n",test_slope(1,1));
printf("2b: encountered %u trees\n",test_slope(3,1));
printf("2c: encountered %u trees\n",test_slope(5,1));
printf("2d: encountered %u trees\n",test_slope(7,1));
printf("2e: encountered %u trees\n",test_slope(1,2));
for(;;) ;
}
// Count the number of trees on a specific slope
unsigned int test_slope(char x_inc, char y_inc) {
char x=0;
unsigned int trees=0;
char* mapline = map;
for(unsigned int y=0; y<MAP_HEIGHT; y+=y_inc) {
if(mapline[x]=='#')
trees++;
x += x_inc;
if(x>=MAP_WIDTH) x -= MAP_WIDTH;
mapline += y_inc*MAP_WIDTH;
}
return trees;
}
char *map =
".#......##..#.....#....#.#.#..."
".#.#...#.##.#..........#...##.."
".........#.....#.####........#."
".......#.#...#.#..............."
"..#....#...#.#...#.#...#.#....."
"...#...........#..#.........#.#"
"....#..#....#..#..#.#...#..##.."
"#...........#..#.....#.......#."
"#..#...#...#.###...#...#.#...#."
"#...#.#.......#...#...#...##.##"
"..#..................#.#.#....#"
"..#.##....#........##.........."
".....#....#....#.#.......#....."
"##.#..##.#.....###.......#....."
"......#...###....#..#.#...#...."
"..............#.........#.##..."
"#......#.............#....#...#"
".#..#......#.###....#...#.....#"
"..#........#.....#.....#...#..#"
".......#...#..............#..#."
"..#...#........#...##........#."
".#........#....#......#......#."
"....#..#.###.......##....#.#..#"
"..#..###..#...................."
"......#...#....#.........#.#..."
"....#.##................#..#..."
"....#......######.....#........"
".#......##.......#....#..##.###"
"..#...##.###..#.......#....#..."
"....#.###...#.#.#........#....."
"...###...#.......#..........#.#"
"..........#...#..........##.#.."
"..#....#........#.....#....#..#"
"..#...#.#....##..#...##....#..."
"........##...#..##.....#......."
"###.......#.#...#...#.......#.#"
"....#.#....##.###........#....."
".....#..............#....##..##"
"#......#.#....#.#......#.....##"
".....#....#..#......#...#......"
"..#.##..#.....#..#....#......#."
".....#.#.#..........##....#...."
".........#..#..........#.#....."
".##..#...#......#.#..#....#...."
"#.#..##.......#.#......##......"
"..#.#....#.#.....#............."
".#.........#.......#..#.#......"
"##.........#..##.#......#......"
"#..#.....#...#.....#.........#."
"..........#..##..##.#..##...###"
"..##.....#...#..##...##.#.#...."
"..#..........#.#.....##.#....#."
".##..#..#.........###.......#.."
"......##....#...##....##......."
".....#.#.##...............#...."
"#..#......#.....#..#..#.#.....#"
".....##.#....#.#.....#.#.#....."
"....#..#.#..##....#.....#....#."
"#...#.....#....#....#.#.#......"
".....#................#.......#"
".......#..#.#...#.#......#..#.#"
"...........#....#....###...#.#."
"#.##....##..###.#.#......#.##.#"
"..##...#.#..#..#...#.....#.#.#."
"#.....###.#..#.#...#.#......#.#"
"..##.#...#...#.#.....#.#......."
"#....#...#.##......#.#......#.."
"..#.....##.....#..............."
".....###...##.#...........#...."
"...#..##.....##....#..........."
".....#..#......#..........#...."
"....##..##.#...#...#.#.....#.##"
".#.....###..###.#...#.#..#....#"
".#..........#...#..#.#.#..#...#"
".##.##..#..#....#....####......"
"....#..#.#..........#.........."
"###...#.#..#..#...#..###......."
"####.#...#....#..#...#..#......"
".....##....#.#...#....##....##."
"....#.#.##....#.##..#....#.#.#."
"#......#..#.###....#####.##...."
"..##..#.#.#..#........##.##..##"
"#.#...#..#..#......#..#.....#.."
".###.....#.#....#.#..##.....#.#"
"....#......#.#...#...#.#....#.#"
".....#.###.##.................."
".#..........#........#.#...##.#"
".##......#.#.#..#....##.###..#."
"..#.##....#....#.........#.#..#"
"........#..#..#.#.####.....##.."
"#..#.##.#......#.#..##.#...#..#"
"..#.#.##..#.##..........#......"
"##.#.....#.#.##..#..##.....##.#"
".##........#..#.....#...#.##.##"
"...#....#.#.#.........##.....#."
"...#....#.#....#...#..#........"
".....#...#..#...#.##......##..."
"##.........#......#..........##"
".#......#.....##....#.#.#.....#"
"..#.###......#..#.#....#.....#."
".#.......#...#...#.#.#.#..##..."
"...#..............#...###.....#"
"...##......#.#..#.#........#.#."
"..##.#....#..........##...#.#.."
"..#...#.....#.######...##...#.."
"#...#...#............#.....#..."
".###..###.##..#.........#......"
".#........##..#....#...#.#..##."
"#.#.##.#.#...###..............."
"..#.#.#......#.#.#....#.....#.#"
".#...........#.##.#..#.###....."
".###.#....#...........##.#.#..."
".#...#...........#..##........."
".#...#.#...........#..###....#."
".##.......#.....#.....##....#.."
"#.......#........#...##.##..#.#"
"....#..###..#.....##.......#..."
"......###.#...#..#....#.#...#.."
"..#..#.......##...#.#.#...#...."
"......#..#.......#.......##.#.."
"#.#....###.....#...#..#...#...."
"#...#.##.#........#..........##"
".....#.#.##.#.#..#..##.......##"
".#.#.......##....#.#..........."
"#..##.............##...#.#..#.."
"#...........#.#......#.##.##..#"
"...#...#...........#....###.#.#"
".##..#.#.#....#....#####......."
"..#...#.....#.#....#..........."
".#..#........#.....#.#......#.."
".#.........#...#...#.#.#..#...."
".##.##......#.#...#.......#...#"
".##...#..#..........#...#.....#"
"#..........#..#...#.#......#..."
"....##......#...##..##..#....#."
".##.......#...#.#..##..#..#...."
".#.#................#....#....."
"..#..#..###.......#............"
"...##.....#..#......#....#....."
"....#...###...#....#..##...#.#."
"#.........#.......#...#....#..."
".#.#...#.#....##....#.#..##.#.."
"...#..#..#....#..#.#..##.....##"
"..#..#.#.#....#...#....#..#...."
"......###.....#...##.#..#.#...#"
".#.#.#..#.##........#.#....#..."
".#..........#....#.#.......#..."
"#.....#........#........#....#."
".#.#..#...#...................#"
"....####..#..#..#..#....#..#.#."
"..##.#..........#.##..#.....##."
"..................##..........#"
"....##....###.....#..#...#.#..."
".##.........#..#..............."
"....##..###....#.##............"
"#.#...###.#..##...#...........#"
".....#..#......#.....#........."
"..#..##...#.....#.....#.#......"
"......#....###.#..#.#.#....#..#"
"#...#.......#.##.....#........."
".#.#..#...#.............##....."
"......#..............#.....#..#"
"......#......###....#...#......"
".....#.....#...#.......###....."
"#..........##......##.#.#.....#"
"....#.......#..#......#.......#"
"..#...#.###...........#..#.###."
".....#...#.#...........#.#...##"
"........#.#.#........#.#.....#."
"....##..##.#.#..#.#....#.#.##.."
"..#.#.#......##.....#...#.#...#"
"##...#..#......#.#.#..#...#...."
"....#..##...........#..#..#..#."
".#..##...#...#...##.#..#.#....#"
".#.....####.#..#..#....##..#.#."
".#....#..#......#.....#.#.#...."
"....#..#.....#......#.........."
"..#.#..###.....#...#...#.....##"
"..#.#...##..#...........####..."
".#.##....##.#......#.....##.#.."
"#.##..#....#.###..........##..."
".###...#......#.#....##........"
"...................#..#.....#.."
"#.#...#.#..#.....#...#..####.##"
"....#.##..##...##.##.....#....."
".#...#.##...........#.......##."
"###..#.....##...#.........##..."
".###....##...###..............."
".#....#####........#.#.#.##...."
".#.#....####.##........#......."
".....#......#.................."
"......###.....##......#..##.#.."
"....#.#...........##.#....##.#."
"...................#.#.#......."
"#.#.#........#..#.......##....."
"..#...#...#....#......#....##.#"
"#..#..............#......#....#"
"......#.........##............."
".....#.#....##..#.......#......"
"......#.......#...........#...."
"....#....#.#..##.#....#...#...."
"#.#.#..#..#.#.#.#...#....#....#"
".#.#....#...#.#..#......#.....#"
".#...........#.#....##.....#..."
"........#...#....#....##.....##"
"#..#..........#..#..#.....#...."
"#.#.###..........#.##....#...##"
"..#................#.##.##....."
"..#...#.##...##...#.........#.."
"#....#......#......#.........#."
"##...#...##.#.........#......#."
".......#.....#................."
"...#...#.....##.........#.#..#."
"..#......#...#.......#......#.#"
"#.......#...#.##.#..##..#......"
".#.#............#...###..#....."
"...#.......##.......#....#..#.."
".....#..#.#....#.#............."
"#....#...##.##....#....##......"
"........#......#.......#....#.."
"..#..#..##......##.#..#.#..##.."
"....##......#.##.##......#....."
"........##.#...#.....#.......#."
"..##.#....#..#......#.##......."
"..##.####.#...#.#....#........."
".#........#.....#..#....#...#.#"
"###....##......#..#..#.##..#..."
"..........###.#..#..#....#....."
"..#.........#....#.....#....#.#"
".#...#.#.....##.#...#...#.#..#."
"....##......##.##.#.....#..#..."
"....#.##...##.......#..##......"
"#..........#..#....#.......#.#."
"..#.....#.................#...."
"..........#.#.#.....#.#....#..#"
".......#..........#.##....#...."
"#..#.....#.......#........#...."
"#.....##..#.........##..#..#.#."
".##.#...#..........#....#......"
"....#..#.#......#.##..#..#.##.."
"...##.####....#.....#.#...##..."
"..#.#....#.#........#.........."
"#...#.#.##.##....##..#...#...#."
"...#.#.......#..#...#..#..##..#"
".....#....#........###.....#..."
".......#..#.##....#.#.....#...."
"....##....#....#.......#.....#."
".........#........###...##....."
"#.#..#...##.........#.#..#....#"
"...##...........#.........#...#"
"......#.#.#.........#..#.#.#..."
"........##.###....#..#.......#."
"....#.#...#......#..#........##"
".#....##....#...#.##.........#."
"####.#..#...........##.#.#....."
"...#....#..#.....#..##.####.#.."
".##...#...........#.#.........#"
"#.#..#..#...#.#.#.........#..#."
"#......###............#...#...."
"..#.......#....#...#...#..#...#"
"#.#.#...##..#...#...#.......##."
"......#.#.......#..........#.#."
"...............#...#..#...#.#.."
".#.#...##.####..##.##....#..##."
"#..####.......##.#........#...#"
"......###....##...#.#..#.##...."
".##.....###..#...#.###.###....."
"..#...#.....#...#..#..##..#...."
"...#...##.....##........#.#.##."
".#...#..#....#....#..###....#.#"
"..#.#.#.#.#..........#.#..#..##"
".......###....................."
"##.#......#.##.....#.........#."
"......................#.#.....#"
"#..#........##.......#..##..#.#"
"#.#.#.....##.#.##.##.#....##..."
".#...#.....#.........#.....#..."
"..#.........#.##.#.###.#......#"
".........#..#.##...#.......###."
".....##........#......#........"
"...#.#...##...#........#.##...."
".........##............#.####.."
"#....#...#...#..#....#..#.#.#.#"
"..#.........#......#.##........"
"....#.....#........#........#.#"
".##.#..#.#..#..###......###...."
"#.###.....#.#.#.##........#..##"
"#.#..#...##.....#....#...#.#..."
"......#....#.....#...#........."
"...#........##.......#.##..####"
"..#..#....#....#..#..#...#.##.."
".##.....#............#...#....."
"......#.......#.....#...#.#.#.."
".........#.....#...##.........."
".....#........##...........#..."
"#.#..##.#...#....#....#........"
"#.##..#.#.......#...#......#..."
"...........#.#..#..#.....##.#.."
"#....#.##.......#......#.##..#."
".....#........#.##.#...#.....#."
".....###..#.......##..........."
".........#.#.#.....#.##.......#"
".......#....#......#.#.....#..."
"##........#...#..#.#.........#."
"##...........#.##...##......#.."
"..#.###.#.#.#...####..#....###."
".........#...#.....##....#.#.##"
".###..###.#.#.....#.##........."
"#..#...#.#.................##.#"
"##.........#.#....#.#...#.###.."
"#.#....#..............#.##.#..."
"...#..#....##.#..#.......#..##."
".#..#.###......##..........#..#"
".##....#.#....#....#.#..#......"
".......#.....#..#....#.##...#.."
"#.#.#.........###..#..#.....#.."
"...##..##...##....#..#......#.."
"..........#....#..........#...."
"#..##..#...#......#.....#.#...."
"#..##..#....#.#.#...#.........."
"......##..#.........#........#."
".##..#..#......###.....#..#...."
".....#..#.##..........#.#..#..."
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.
People use them as a speed contest, interview prep, company training, university coursework, practice problems, or to challenge each other.
See https://adventofcode.com/2020/about

View File

@ -0,0 +1,66 @@
// LongLong implementation supporting integer addition and multiplication for 64bit signed integers
#include <stdlib.h>
struct LongLong {
// The lower 32bit
long low;
// The upper 32bit
long high;
};
// Creates a LongLong for a signed long value
struct LongLong toLongLong(long l) {
if(l<0)
return {l,-1l};
else
return {l,0l};
}
// Add two LongLongs together
struct LongLong plusLongLong(__ma struct LongLong a, __ma struct LongLong b) {
__ma struct LongLong sum;
asm {
clc
lda a
adc b
sta sum
lda a+1
adc b+1
sta sum+1
lda a+2
adc b+2
sta sum+2
lda a+3
adc b+3
sta sum+3
lda a+4
adc b+4
sta sum+4
lda a+5
adc b+5
sta sum+5
lda a+6
adc b+6
sta sum+6
lda a+7
adc b+7
sta sum+7
}
return sum;
}
struct LongLong * SCREEN = 0x0400;
void main() {
struct LongLong a = toLongLong(1000);
struct LongLong b = toLongLong(-2000);
struct LongLong c = plusLongLong(a,b);
SCREEN[0] = a;
SCREEN[2] = b;
SCREEN[4] = c;
}

View File

@ -6,7 +6,7 @@ void* const NUL = (void*)0;
// Works
// char*[] msgs = { (char*)"hello", (char*)"cruel", (char*)"world", (char*)NUL };
// Not working
char*[] msgs = { "hello", "cruel", "world", NUL };
char* msgs[] = { "hello", "cruel", "world", NUL };
void main() {
char i=0;

View File

@ -1,7 +1,7 @@
// Tests the target platform ASM6502
#pragma target(asm6502)
#pragma start_address(0x2000)
#pragma start_address(0x3000)
unsigned char TABLE[10];

View File

@ -0,0 +1,26 @@
// Test combining unwind structs with classic structs
struct Point {
char x;
char y;
};
struct Point * const SCREEN = 0x0400;
void main() {
// Initialize classic struct
__ma struct Point p1 = { 1, 2 };
SCREEN[0] = p1;
// Copy classic struct to unwound struct
struct Point p2 = p1;
SCREEN[2] = p2;
// Set in classic struct
p1.x = 3;
SCREEN[4] = p1;
// Set in unwound struct
p2.x = 4;
SCREEN[6] = p2;
// Copy unwound struct to classic struct
p1 = p2;
SCREEN[8] = p1;
}

View File

@ -0,0 +1,37 @@
// Test combining unwind structs with classic structs
// Function calls parameter passing
struct Point {
char x;
char y;
};
struct Point * const SCREEN = 0x0400;
void main() {
// Initialize classic struct
__ma struct Point p1 = { 1, 2 };
// Pass classic struct to function taking unwound struct
print1(p1, 0);
// Pass classic struct to function taking classic struct
print2(p1, 2);
// Initialize unwound struct
struct Point p2 = { 3, 4};
// Pass unwound struct to function taking unwound struct
print1(p2, 4);
// Pass unwound struct to function taking classic struct
print2(p2, 6);
}
// Function taking unwound struct as parameter
void print1(struct Point p, char idx) {
// Print unwound struct
SCREEN[idx] = p;
}
// Function taking classic struct as parameter
void print2(__ma struct Point p, char idx) {
// Print unwound struct
SCREEN[idx] = p;
}

View File

@ -0,0 +1,39 @@
// Test combining unwind structs with classic structs
// Function calls return value
struct Point {
char x;
char y;
};
struct Point * const SCREEN = 0x0400;
void main() {
// Initialize classic struct from function returning unwound
__ma struct Point p1 = point1(1, 2);
SCREEN[0] = p1;
// Initialize classic struct from function returning classic
//p1 = point2(2, 3);
//SCREEN[2] = p1;
// Initialize unwound struct from function returning unwound
//struct Point p2 = point1(3,4);
//SCREEN[4] = p2;
// Initialize unwound struct from function returning classic
//p2 = point2(5,6);
//SCREEN[6] = p2;
}
// Function returning unwound struct
struct Point point1(char x, char y) {
// Print unwound struct
struct Point p = { x, y };
return p;
}
// Function returning classic struct
//__ma struct Point point2(char x, char y) {
// // Print unwound struct
// struct Point p = { x, y };
// return p;
//}

13
src/test/kc/varcall-1.c Normal file
View File

@ -0,0 +1,13 @@
// Test __varcall calling convention
// Parameter passing
void main() {
setbg(0);
setbg(0x0b);
}
char * const BGCOL = 0xd021;
__varcall void setbg(char col) {
*BGCOL = col;
}

17
src/test/kc/varcall-2.c Normal file
View File

@ -0,0 +1,17 @@
// Test __varcall calling convention
// Return value
char * const BGCOL = 0xd021;
void main() {
char a = 1;
*BGCOL = a;
a = plus(a, 1);
*BGCOL = a;
a = plus(a, a);
*BGCOL = a;
}
__varcall char plus(char a, char b) {
return a+b;
}

17
src/test/kc/varcall-3.c Normal file
View File

@ -0,0 +1,17 @@
// Test __varcall calling convention
// Larger type parameter & return value
int * const BGCOL = 0xd020;
void main() {
int a = 0x0102;
*BGCOL = a;
a = plus(a, 0x0203);
*BGCOL = a;
a = plus(a, a);
*BGCOL = a;
}
__varcall int plus(int a, int b) {
return a+b;
}

22
src/test/kc/varcall-4.c Normal file
View File

@ -0,0 +1,22 @@
// Test __varcall calling convention
// Struct parameter & return value
struct Cols {
char border;
char bg;
};
struct Cols * const COLS = 0xd020;
void main() {
struct Cols a = { 1, 2 };
//*COLS = a;
a = plus(a, { 2, 3 } );
*COLS = a;
//a = plus(a, a);
//*COLS = a;
}
__varcall struct Cols plus(struct Cols a, struct Cols b) {
return { a.border+b.border, a.bg+b.bg };
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,674 @@
void main()
main: scope:[main] from
[0] phi()
[1] call clrscr
to:main::@19
main::@19: scope:[main] from main
[2] phi()
[3] call cputs
to:main::@20
main::@20: scope:[main] from main::@19
[4] phi()
[5] call printf_uint
to:main::@21
main::@21: scope:[main] from main::@20
[6] phi()
[7] call cputs
to:main::@1
main::@1: scope:[main] from main::@21 main::@24
[8] main::i#2 = phi( main::@21/0, main::@24/main::i#1 )
[9] if(main::i#2<main::num_entries#0) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1
[10] phi()
[11] call cputs
to:main::@22
main::@22: scope:[main] from main::@3
[12] phi()
[13] call printf_uint
to:main::@23
main::@23: scope:[main] from main::@22
[14] phi()
[15] call cputs
to:main::@9
main::@9: scope:[main] from main::@23 main::@38
[16] main::i1#2 = phi( main::@23/0, main::@38/main::i1#1 )
[17] if(main::i1#2<main::num_entries#0) goto main::@10
to:main::@return
main::@return: scope:[main] from main::@9
[18] return
to:@return
main::@10: scope:[main] from main::@9
[19] main::j1#0 = main::i1#2 + 1
to:main::@11
main::@11: scope:[main] from main::@10 main::@16
[20] main::j1#2 = phi( main::@10/main::j1#0, main::@16/main::j1#1 )
[21] if(main::j1#2<main::num_entries#0) goto main::@12
to:main::@13
main::@13: scope:[main] from main::@11
[22] phi()
[23] call cputs
to:main::@38
main::@38: scope:[main] from main::@13
[24] main::i1#1 = ++ main::i1#2
to:main::@9
main::@12: scope:[main] from main::@11
[25] main::k#0 = main::j1#2 + 1
to:main::@14
main::@14: scope:[main] from main::@12 main::@17
[26] main::k#10 = phi( main::@12/main::k#0, main::@17/main::k#1 )
[27] if(main::k#10<main::num_entries#0) goto main::@15
to:main::@16
main::@16: scope:[main] from main::@14
[28] main::j1#1 = ++ main::j1#2
to:main::@11
main::@15: scope:[main] from main::@14
[29] main::$41 = main::i1#2 << 1
[30] main::$42 = main::j1#2 << 1
[31] main::$53 = entries + main::$41
[32] main::$54 = entries + main::$42
[33] main::$21 = *main::$53 + *main::$54
[34] main::$43 = main::k#10 << 1
[35] main::$55 = entries + main::$43
[36] main::$22 = main::$21 + *main::$55
[37] if(main::$22!=$7e4) goto main::@17
to:main::@18
main::@18: scope:[main] from main::@15
[38] phi()
[39] call cputs
to:main::@39
main::@39: scope:[main] from main::@18
[40] phi()
[41] call cputs
to:main::@40
main::@40: scope:[main] from main::@39
[42] printf_uint::uvalue#6 = main::i1#2
[43] call printf_uint
to:main::@41
main::@41: scope:[main] from main::@40
[44] phi()
[45] call cputs
to:main::@42
main::@42: scope:[main] from main::@41
[46] main::$56 = entries + main::$41
[47] printf_uint::uvalue#7 = *main::$56
[48] call printf_uint
to:main::@43
main::@43: scope:[main] from main::@42
[49] phi()
[50] call cputs
to:main::@44
main::@44: scope:[main] from main::@43
[51] printf_uint::uvalue#8 = main::j1#2
[52] call printf_uint
to:main::@45
main::@45: scope:[main] from main::@44
[53] phi()
[54] call cputs
to:main::@46
main::@46: scope:[main] from main::@45
[55] main::$57 = entries + main::$42
[56] printf_uint::uvalue#9 = *main::$57
[57] call printf_uint
to:main::@47
main::@47: scope:[main] from main::@46
[58] phi()
[59] call cputs
to:main::@48
main::@48: scope:[main] from main::@47
[60] printf_uint::uvalue#10 = main::k#10
[61] call printf_uint
to:main::@49
main::@49: scope:[main] from main::@48
[62] phi()
[63] call cputs
to:main::@50
main::@50: scope:[main] from main::@49
[64] main::$58 = entries + main::$43
[65] printf_uint::uvalue#11 = *main::$58
[66] call printf_uint
to:main::@51
main::@51: scope:[main] from main::@50
[67] phi()
[68] call cputs
to:main::@52
main::@52: scope:[main] from main::@51
[69] main::$59 = entries + main::$41
[70] mul16u::a#2 = *main::$59
[71] main::$60 = entries + main::$43
[72] mul16u::b#1 = *main::$60
[73] call mul16u
[74] mul16u::return#3 = mul16u::res#2
to:main::@53
main::@53: scope:[main] from main::@52
[75] main::mul1#0 = mul16u::return#3
[76] mul16u::a#3 = < main::mul1#0
[77] main::$61 = entries + main::$42
[78] mul16u::b#2 = *main::$61
[79] call mul16u
[80] mul16u::return#4 = mul16u::res#2
to:main::@54
main::@54: scope:[main] from main::@53
[81] main::mul2#0 = mul16u::return#4
[82] call cputs
to:main::@55
main::@55: scope:[main] from main::@54
[83] printf_ulong::uvalue#1 = main::mul2#0
[84] call printf_ulong
to:main::@56
main::@56: scope:[main] from main::@55
[85] phi()
[86] call cputs
to:main::@17
main::@17: scope:[main] from main::@15 main::@56
[87] main::k#1 = ++ main::k#10
to:main::@14
main::@2: scope:[main] from main::@1
[88] main::j#0 = main::i#2 + 1
to:main::@4
main::@4: scope:[main] from main::@2 main::@7
[89] main::j#10 = phi( main::@2/main::j#0, main::@7/main::j#1 )
[90] if(main::j#10<main::num_entries#0) goto main::@5
to:main::@6
main::@6: scope:[main] from main::@4
[91] phi()
[92] call cputs
to:main::@24
main::@24: scope:[main] from main::@6
[93] main::i#1 = ++ main::i#2
to:main::@1
main::@5: scope:[main] from main::@4
[94] main::$34 = main::i#2 << 1
[95] main::$35 = main::j#10 << 1
[96] main::$47 = entries + main::$34
[97] main::$48 = entries + main::$35
[98] main::$8 = *main::$47 + *main::$48
[99] if(main::$8!=$7e4) goto main::@7
to:main::@8
main::@8: scope:[main] from main::@5
[100] phi()
[101] call cputs
to:main::@25
main::@25: scope:[main] from main::@8
[102] phi()
[103] call cputs
to:main::@26
main::@26: scope:[main] from main::@25
[104] printf_uint::uvalue#2 = main::i#2
[105] call printf_uint
to:main::@27
main::@27: scope:[main] from main::@26
[106] phi()
[107] call cputs
to:main::@28
main::@28: scope:[main] from main::@27
[108] main::$49 = entries + main::$34
[109] printf_uint::uvalue#3 = *main::$49
[110] call printf_uint
to:main::@29
main::@29: scope:[main] from main::@28
[111] phi()
[112] call cputs
to:main::@30
main::@30: scope:[main] from main::@29
[113] printf_uint::uvalue#4 = main::j#10
[114] call printf_uint
to:main::@31
main::@31: scope:[main] from main::@30
[115] phi()
[116] call cputs
to:main::@32
main::@32: scope:[main] from main::@31
[117] main::$50 = entries + main::$35
[118] printf_uint::uvalue#5 = *main::$50
[119] call printf_uint
to:main::@33
main::@33: scope:[main] from main::@32
[120] phi()
[121] call cputs
to:main::@34
main::@34: scope:[main] from main::@33
[122] main::$51 = entries + main::$34
[123] mul16u::a#1 = *main::$51
[124] main::$52 = entries + main::$35
[125] mul16u::b#0 = *main::$52
[126] call mul16u
[127] mul16u::return#2 = mul16u::res#2
to:main::@35
main::@35: scope:[main] from main::@34
[128] main::mul#0 = mul16u::return#2
[129] call cputs
to:main::@36
main::@36: scope:[main] from main::@35
[130] printf_ulong::uvalue#0 = main::mul#0
[131] call printf_ulong
to:main::@37
main::@37: scope:[main] from main::@36
[132] phi()
[133] call cputs
to:main::@7
main::@7: scope:[main] from main::@37 main::@5
[134] main::j#1 = ++ main::j#10
to:main::@4
void clrscr()
clrscr: scope:[clrscr] from main
[135] memset::str#7 = (void*)*SAVMSC
[136] call memset
to:clrscr::@1
clrscr::@1: scope:[clrscr] from clrscr
[137] *OLDCHR = 0
[138] call gotoxy
to:clrscr::@return
clrscr::@return: scope:[clrscr] from clrscr::@1
[139] return
to:@return
void cputs(to_nomodify byte* cputs::s)
cputs: scope:[cputs] from main::@13 main::@18 main::@19 main::@21 main::@23 main::@25 main::@27 main::@29 main::@3 main::@31 main::@33 main::@35 main::@37 main::@39 main::@41 main::@43 main::@45 main::@47 main::@49 main::@51 main::@54 main::@56 main::@6 main::@8 printf_number_buffer::@2
[140] cputs::s#27 = phi( main::@13/main::s4, main::@18/main::s5, main::@19/main::s, main::@21/main::s1, main::@23/main::s1, main::@25/main::s6, main::@27/main::s7, main::@3/main::s2, main::@29/main::s8, main::@31/main::s7, main::@33/main::s10, main::@35/main::s11, main::@37/main::s5, main::@39/main::s6, main::@41/main::s7, main::@43/main::s8, main::@45/main::s7, main::@47/main::s8, main::@49/main::s7, main::@51/main::s10, main::@54/main::s11, main::@56/main::s5, main::@6/main::s4, main::@8/main::s5, printf_number_buffer::@2/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
[141] cputs::s#26 = phi( cputs/cputs::s#27, cputs::@2/cputs::s#0 )
[142] cputs::c#1 = *cputs::s#26
[143] cputs::s#0 = ++ cputs::s#26
[144] if(0!=cputs::c#1) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[145] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[146] cputc::c = cputs::c#1
[147] call cputc
to:cputs::@1
void printf_uint(word printf_uint::uvalue , byte printf_uint::format_min_length , byte printf_uint::format_justify_left , byte printf_uint::format_sign_always , byte printf_uint::format_zero_padding , byte printf_uint::format_upper_case , byte printf_uint::format_radix)
printf_uint: scope:[printf_uint] from main::@20 main::@22 main::@26 main::@28 main::@30 main::@32 main::@40 main::@42 main::@44 main::@46 main::@48 main::@50
[148] printf_uint::uvalue#12 = phi( main::@20/main::num_entries#0, main::@22/main::num_entries#0, main::@26/printf_uint::uvalue#2, main::@28/printf_uint::uvalue#3, main::@30/printf_uint::uvalue#4, main::@32/printf_uint::uvalue#5, main::@40/printf_uint::uvalue#6, main::@42/printf_uint::uvalue#7, main::@44/printf_uint::uvalue#8, main::@46/printf_uint::uvalue#9, main::@48/printf_uint::uvalue#10, main::@50/printf_uint::uvalue#11 )
to:printf_uint::@1
printf_uint::@1: scope:[printf_uint] from printf_uint
[149] *((byte*)&printf_buffer) = 0
[150] utoa::value#1 = printf_uint::uvalue#12
[151] call utoa
to:printf_uint::@2
printf_uint::@2: scope:[printf_uint] from printf_uint::@1
[152] printf_number_buffer::buffer_sign#1 = *((byte*)&printf_buffer)
[153] call printf_number_buffer
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint::@2
[154] return
to:@return
dword mul16u(word mul16u::a , word mul16u::b)
mul16u: scope:[mul16u] from main::@34 main::@52 main::@53
[155] mul16u::a#7 = phi( main::@34/mul16u::a#1, main::@52/mul16u::a#2, main::@53/mul16u::a#3 )
[155] mul16u::b#3 = phi( main::@34/mul16u::b#0, main::@52/mul16u::b#1, main::@53/mul16u::b#2 )
[156] mul16u::mb#0 = (dword)mul16u::b#3
to:mul16u::@1
mul16u::@1: scope:[mul16u] from mul16u mul16u::@3
[157] mul16u::mb#2 = phi( mul16u/mul16u::mb#0, mul16u::@3/mul16u::mb#1 )
[157] mul16u::res#2 = phi( mul16u/0, mul16u::@3/mul16u::res#6 )
[157] mul16u::a#4 = phi( mul16u/mul16u::a#7, mul16u::@3/mul16u::a#0 )
[158] if(mul16u::a#4!=0) goto mul16u::@2
to:mul16u::@return
mul16u::@return: scope:[mul16u] from mul16u::@1
[159] return
to:@return
mul16u::@2: scope:[mul16u] from mul16u::@1
[160] mul16u::$1 = mul16u::a#4 & 1
[161] if(mul16u::$1==0) goto mul16u::@3
to:mul16u::@4
mul16u::@4: scope:[mul16u] from mul16u::@2
[162] mul16u::res#1 = mul16u::res#2 + mul16u::mb#2
to:mul16u::@3
mul16u::@3: scope:[mul16u] from mul16u::@2 mul16u::@4
[163] mul16u::res#6 = phi( mul16u::@2/mul16u::res#2, mul16u::@4/mul16u::res#1 )
[164] mul16u::a#0 = mul16u::a#4 >> 1
[165] mul16u::mb#1 = mul16u::mb#2 << 1
to:mul16u::@1
void printf_ulong(dword printf_ulong::uvalue , byte printf_ulong::format_min_length , byte printf_ulong::format_justify_left , byte printf_ulong::format_sign_always , byte printf_ulong::format_zero_padding , byte printf_ulong::format_upper_case , byte printf_ulong::format_radix)
printf_ulong: scope:[printf_ulong] from main::@36 main::@55
[166] printf_ulong::uvalue#2 = phi( main::@36/printf_ulong::uvalue#0, main::@55/printf_ulong::uvalue#1 )
to:printf_ulong::@1
printf_ulong::@1: scope:[printf_ulong] from printf_ulong
[167] *((byte*)&printf_buffer) = 0
[168] ultoa::value#1 = printf_ulong::uvalue#2
[169] call ultoa
to:printf_ulong::@2
printf_ulong::@2: scope:[printf_ulong] from printf_ulong::@1
[170] printf_number_buffer::buffer_sign#0 = *((byte*)&printf_buffer)
[171] call printf_number_buffer
to:printf_ulong::@return
printf_ulong::@return: scope:[printf_ulong] from printf_ulong::@2
[172] return
to:@return
void* memset(void* memset::str , byte memset::c , word memset::num)
memset: scope:[memset] from clrscr newline::@4
[173] memset::str#3 = phi( clrscr/memset::str#7, newline::@4/memset::str#8 )
[173] memset::num#2 = phi( clrscr/(word)$28*$18, newline::@4/$28 )
[174] if(memset::num#2<=0) goto memset::@return
to:memset::@1
memset::@1: scope:[memset] from memset
[175] memset::end#0 = (byte*)memset::str#3 + memset::num#2
[176] memset::dst#4 = (byte*)memset::str#3
to:memset::@2
memset::@2: scope:[memset] from memset::@1 memset::@3
[177] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 )
[178] if(memset::dst#2!=memset::end#0) goto memset::@3
to:memset::@return
memset::@return: scope:[memset] from memset memset::@2
[179] return
to:@return
memset::@3: scope:[memset] from memset::@2
[180] *memset::dst#2 = 0
[181] memset::dst#1 = ++ memset::dst#2
to:memset::@2
void gotoxy(byte gotoxy::x , byte gotoxy::y)
gotoxy: scope:[gotoxy] from clrscr::@1
[182] *COLCRS = gotoxy::x#1
[183] *ROWCRS = gotoxy::y#1
[184] call setcursor
to:gotoxy::@return
gotoxy::@return: scope:[gotoxy] from gotoxy
[185] return
to:@return
void cputc(volatile byte cputc::c)
cputc: scope:[cputc] from cputs::@2 printf_number_buffer::@3
[186] if(cputc::c==' 'at) goto cputc::@1
to:cputc::@3
cputc::@3: scope:[cputc] from cputc
[187] if(cputc::c=='
'at) goto cputc::@2
to:cputc::@8
cputc::@8: scope:[cputc] from cputc::@3
[188] if(cputc::c==$9b) goto cputc::@2
to:cputc::convertToScreenCode1
cputc::convertToScreenCode1: scope:[cputc] from cputc::@8
[189] cputc::convertToScreenCode1_return#0 = rawmap[*cputc::convertToScreenCode1_v#0]
to:cputc::@6
cputc::@6: scope:[cputc] from cputc::convertToScreenCode1
[190] phi()
[191] call putchar
to:cputc::@7
cputc::@7: scope:[cputc] from cputc::@6
[192] *COLCRS = ++ *COLCRS
[193] if(*COLCRS==$28) goto cputc::@5
to:cputc::@4
cputc::@4: scope:[cputc] from cputc::@7
[194] phi()
[195] call setcursor
to:cputc::@return
cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@4 cputc::@5
[196] return
to:@return
cputc::@5: scope:[cputc] from cputc::@7
[197] *COLCRS = 0
[198] call newline
to:cputc::@return
cputc::@2: scope:[cputc] from cputc::@3 cputc::@8
[199] *COLCRS = 0
[200] call newline
to:cputc::@return
cputc::@1: scope:[cputc] from cputc
[201] *COLCRS = 0
[202] call setcursor
to:cputc::@return
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
utoa: scope:[utoa] from printf_uint::@1
[203] phi()
to:utoa::@1
utoa::@1: scope:[utoa] from utoa utoa::@4
[204] utoa::buffer#11 = phi( utoa::@4/utoa::buffer#14, utoa/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[204] utoa::started#2 = phi( utoa::@4/utoa::started#4, utoa/0 )
[204] utoa::value#2 = phi( utoa::@4/utoa::value#6, utoa/utoa::value#1 )
[204] utoa::digit#2 = phi( utoa::@4/utoa::digit#1, utoa/0 )
[205] if(utoa::digit#2<5-1) goto utoa::@2
to:utoa::@3
utoa::@3: scope:[utoa] from utoa::@1
[206] utoa::$11 = (byte)utoa::value#2
[207] *utoa::buffer#11 = DIGITS[utoa::$11]
[208] utoa::buffer#3 = ++ utoa::buffer#11
[209] *utoa::buffer#3 = 0
to:utoa::@return
utoa::@return: scope:[utoa] from utoa::@3
[210] return
to:@return
utoa::@2: scope:[utoa] from utoa::@1
[211] utoa::$10 = utoa::digit#2 << 1
[212] utoa::digit_value#0 = RADIX_DECIMAL_VALUES[utoa::$10]
[213] if(0!=utoa::started#2) goto utoa::@5
to:utoa::@7
utoa::@7: scope:[utoa] from utoa::@2
[214] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5
to:utoa::@4
utoa::@4: scope:[utoa] from utoa::@6 utoa::@7
[215] utoa::buffer#14 = phi( utoa::@7/utoa::buffer#11, utoa::@6/utoa::buffer#4 )
[215] utoa::started#4 = phi( utoa::@7/utoa::started#2, utoa::@6/1 )
[215] utoa::value#6 = phi( utoa::@7/utoa::value#2, utoa::@6/utoa::value#0 )
[216] utoa::digit#1 = ++ utoa::digit#2
to:utoa::@1
utoa::@5: scope:[utoa] from utoa::@2 utoa::@7
[217] utoa_append::buffer#0 = utoa::buffer#11
[218] utoa_append::value#0 = utoa::value#2
[219] utoa_append::sub#0 = utoa::digit_value#0
[220] call utoa_append
[221] utoa_append::return#0 = utoa_append::value#2
to:utoa::@6
utoa::@6: scope:[utoa] from utoa::@5
[222] utoa::value#0 = utoa_append::return#0
[223] utoa::buffer#4 = ++ utoa::buffer#11
to:utoa::@4
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
printf_number_buffer: scope:[printf_number_buffer] from printf_uint::@2 printf_ulong::@2
[224] printf_number_buffer::buffer_sign#10 = phi( printf_uint::@2/printf_number_buffer::buffer_sign#1, printf_ulong::@2/printf_number_buffer::buffer_sign#0 )
to:printf_number_buffer::@1
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer
[225] if(0==printf_number_buffer::buffer_sign#10) goto printf_number_buffer::@2
to:printf_number_buffer::@3
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@1
[226] cputc::c = printf_number_buffer::buffer_sign#10
[227] call cputc
to:printf_number_buffer::@2
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@3
[228] phi()
[229] call cputs
to:printf_number_buffer::@return
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@2
[230] return
to:@return
void ultoa(dword ultoa::value , byte* ultoa::buffer , byte ultoa::radix)
ultoa: scope:[ultoa] from printf_ulong::@1
[231] phi()
to:ultoa::@1
ultoa::@1: scope:[ultoa] from ultoa ultoa::@4
[232] ultoa::buffer#11 = phi( ultoa::@4/ultoa::buffer#14, ultoa/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[232] ultoa::started#2 = phi( ultoa::@4/ultoa::started#4, ultoa/0 )
[232] ultoa::value#2 = phi( ultoa::@4/ultoa::value#6, ultoa/ultoa::value#1 )
[232] ultoa::digit#2 = phi( ultoa::@4/ultoa::digit#1, ultoa/0 )
[233] if(ultoa::digit#2<$a-1) goto ultoa::@2
to:ultoa::@3
ultoa::@3: scope:[ultoa] from ultoa::@1
[234] ultoa::$11 = (byte)ultoa::value#2
[235] *ultoa::buffer#11 = DIGITS[ultoa::$11]
[236] ultoa::buffer#3 = ++ ultoa::buffer#11
[237] *ultoa::buffer#3 = 0
to:ultoa::@return
ultoa::@return: scope:[ultoa] from ultoa::@3
[238] return
to:@return
ultoa::@2: scope:[ultoa] from ultoa::@1
[239] ultoa::$10 = ultoa::digit#2 << 2
[240] ultoa::digit_value#0 = RADIX_DECIMAL_VALUES_LONG[ultoa::$10]
[241] if(0!=ultoa::started#2) goto ultoa::@5
to:ultoa::@7
ultoa::@7: scope:[ultoa] from ultoa::@2
[242] if(ultoa::value#2>=ultoa::digit_value#0) goto ultoa::@5
to:ultoa::@4
ultoa::@4: scope:[ultoa] from ultoa::@6 ultoa::@7
[243] ultoa::buffer#14 = phi( ultoa::@7/ultoa::buffer#11, ultoa::@6/ultoa::buffer#4 )
[243] ultoa::started#4 = phi( ultoa::@7/ultoa::started#2, ultoa::@6/1 )
[243] ultoa::value#6 = phi( ultoa::@7/ultoa::value#2, ultoa::@6/ultoa::value#0 )
[244] ultoa::digit#1 = ++ ultoa::digit#2
to:ultoa::@1
ultoa::@5: scope:[ultoa] from ultoa::@2 ultoa::@7
[245] ultoa_append::buffer#0 = ultoa::buffer#11
[246] ultoa_append::value#0 = ultoa::value#2
[247] ultoa_append::sub#0 = ultoa::digit_value#0
[248] call ultoa_append
[249] ultoa_append::return#0 = ultoa_append::value#2
to:ultoa::@6
ultoa::@6: scope:[ultoa] from ultoa::@5
[250] ultoa::value#0 = ultoa_append::return#0
[251] ultoa::buffer#4 = ++ ultoa::buffer#11
to:ultoa::@4
void setcursor()
setcursor: scope:[setcursor] from cputc::@1 cputc::@4 gotoxy newline::@1 putchar::@1
[252] *(*OLDADR) = *OLDCHR
[253] call cursorLocation
[254] cursorLocation::return#3 = cursorLocation::return#1
to:setcursor::@3
setcursor::@3: scope:[setcursor] from setcursor
[255] setcursor::loc#0 = cursorLocation::return#3
[256] setcursor::c#0 = *setcursor::loc#0
[257] *OLDCHR = setcursor::c#0
[258] *OLDADR = setcursor::loc#0
to:setcursor::@2
setcursor::@2: scope:[setcursor] from setcursor::@3
[259] *CRSINH = 0
[260] setcursor::c#1 = setcursor::c#0 ^ $80
to:setcursor::@1
setcursor::@1: scope:[setcursor] from setcursor::@2
[261] *(*OLDADR) = setcursor::c#1
to:setcursor::@return
setcursor::@return: scope:[setcursor] from setcursor::@1
[262] return
to:@return
void putchar(byte putchar::code)
putchar: scope:[putchar] from cputc::@6
[263] *(*OLDADR) = *OLDCHR
[264] call cursorLocation
[265] cursorLocation::return#0 = cursorLocation::return#1
to:putchar::@1
putchar::@1: scope:[putchar] from putchar
[266] putchar::loc#0 = cursorLocation::return#0
[267] putchar::newChar#0 = cputc::convertToScreenCode1_return#0
[268] *putchar::loc#0 = putchar::newChar#0
[269] *OLDCHR = putchar::newChar#0
[270] call setcursor
to:putchar::@return
putchar::@return: scope:[putchar] from putchar::@1
[271] return
to:@return
void newline()
newline: scope:[newline] from cputc::@2 cputc::@5
[272] *ROWCRS = ++ *ROWCRS
[273] if(*ROWCRS!=$18) goto newline::@1
to:newline::@3
newline::@3: scope:[newline] from newline
[274] *(*OLDADR) = *(*OLDADR) ^ $80
to:newline::@2
newline::@2: scope:[newline] from newline::@3
[275] newline::start#0 = *SAVMSC
[276] memcpy::source#0 = newline::start#0 + $28
[277] memcpy::destination#0 = (void*)newline::start#0
[278] call memcpy
to:newline::@4
newline::@4: scope:[newline] from newline::@2
[279] memset::str#0 = newline::start#0 + (word)$28*$17
[280] memset::str#8 = (void*)memset::str#0
[281] call memset
to:newline::@5
newline::@5: scope:[newline] from newline::@4
[282] *ROWCRS = (byte)$18-1
to:newline::@1
newline::@1: scope:[newline] from newline newline::@5
[283] phi()
[284] call setcursor
to:newline::@return
newline::@return: scope:[newline] from newline::@1
[285] return
to:@return
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
utoa_append: scope:[utoa_append] from utoa::@5
[286] phi()
to:utoa_append::@1
utoa_append::@1: scope:[utoa_append] from utoa_append utoa_append::@2
[287] utoa_append::digit#2 = phi( utoa_append/0, utoa_append::@2/utoa_append::digit#1 )
[287] utoa_append::value#2 = phi( utoa_append/utoa_append::value#0, utoa_append::@2/utoa_append::value#1 )
[288] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2
to:utoa_append::@3
utoa_append::@3: scope:[utoa_append] from utoa_append::@1
[289] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2]
to:utoa_append::@return
utoa_append::@return: scope:[utoa_append] from utoa_append::@3
[290] return
to:@return
utoa_append::@2: scope:[utoa_append] from utoa_append::@1
[291] utoa_append::digit#1 = ++ utoa_append::digit#2
[292] utoa_append::value#1 = utoa_append::value#2 - utoa_append::sub#0
to:utoa_append::@1
dword ultoa_append(byte* ultoa_append::buffer , dword ultoa_append::value , dword ultoa_append::sub)
ultoa_append: scope:[ultoa_append] from ultoa::@5
[293] phi()
to:ultoa_append::@1
ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2
[294] ultoa_append::digit#2 = phi( ultoa_append/0, ultoa_append::@2/ultoa_append::digit#1 )
[294] ultoa_append::value#2 = phi( ultoa_append/ultoa_append::value#0, ultoa_append::@2/ultoa_append::value#1 )
[295] if(ultoa_append::value#2>=ultoa_append::sub#0) goto ultoa_append::@2
to:ultoa_append::@3
ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1
[296] *ultoa_append::buffer#0 = DIGITS[ultoa_append::digit#2]
to:ultoa_append::@return
ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3
[297] return
to:@return
ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1
[298] ultoa_append::digit#1 = ++ ultoa_append::digit#2
[299] ultoa_append::value#1 = ultoa_append::value#2 - ultoa_append::sub#0
to:ultoa_append::@1
byte* cursorLocation()
cursorLocation: scope:[cursorLocation] from putchar setcursor
[300] cursorLocation::$3 = (word)*ROWCRS
[301] cursorLocation::$4 = cursorLocation::$3 << 2
[302] cursorLocation::$5 = cursorLocation::$4 + cursorLocation::$3
[303] cursorLocation::$0 = cursorLocation::$5 << 3
[304] cursorLocation::$1 = *SAVMSC + cursorLocation::$0
[305] cursorLocation::return#1 = cursorLocation::$1 + *COLCRS
to:cursorLocation::@return
cursorLocation::@return: scope:[cursorLocation] from cursorLocation
[306] return
to:@return
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
memcpy: scope:[memcpy] from newline::@2
[307] memcpy::src_end#0 = (byte*)(void*)memcpy::source#0 + memcpy::num#0
[308] memcpy::src#4 = (byte*)(void*)memcpy::source#0
[309] memcpy::dst#4 = (byte*)memcpy::destination#0
to:memcpy::@1
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
[310] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
[310] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
[311] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
to:memcpy::@return
memcpy::@return: scope:[memcpy] from memcpy::@1
[312] return
to:@return
memcpy::@2: scope:[memcpy] from memcpy::@1
[313] *memcpy::dst#2 = *memcpy::src#2
[314] memcpy::dst#1 = ++ memcpy::dst#2
[315] memcpy::src#1 = ++ memcpy::src#2
to:memcpy::@1

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,354 @@
const word* COLCRS = (word*) 85
const nomodify byte* CRSINH = (byte*) 752
const byte* DIGITS[] = "0123456789abcdef"atz
const byte OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
const nomodify byte** OLDADR = (byte**) 94
const nomodify byte* OLDCHR = (byte*) 93
const byte RADIX::BINARY = 2
const byte RADIX::DECIMAL = $a
const byte RADIX::HEXADECIMAL = $10
const byte RADIX::OCTAL = 8
const word* RADIX_DECIMAL_VALUES[] = { $2710, $3e8, $64, $a }
const dword* RADIX_DECIMAL_VALUES_LONG[] = { $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a }
const byte* ROWCRS = (byte*) 84
const nomodify byte** SAVMSC = (byte**) 88
const byte SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
const byte SIZEOF_WORD = 2
void clrscr()
void cputc(volatile byte cputc::c)
volatile byte cputc::c loadstore zp[1]:161 7.750002500125E10
byte cputc::convertToScreenCode1_return
byte cputc::convertToScreenCode1_return#0 reg byte x 1.833333333336667E11
byte* cputc::convertToScreenCode1_v
const byte* cputc::convertToScreenCode1_v#0 convertToScreenCode1_v = &cputc::c
void cputs(to_nomodify byte* cputs::s)
byte cputs::c
byte cputs::c#1 reg byte a 1.0000000001E10
to_nomodify byte* cputs::s
to_nomodify byte* cputs::s#0 s zp[2]:138 5.0000000005E9
to_nomodify byte* cputs::s#26 s zp[2]:138 1.5000500002E10
to_nomodify byte* cputs::s#27 s zp[2]:138 1000001.0
byte* cursorLocation()
word~ cursorLocation::$0 zp[2]:166 2.00000000000002E14
byte*~ cursorLocation::$1 zp[2]:166 2.00000000000002E14
word~ cursorLocation::$3 zp[2]:166 1.500000000000015E14
word~ cursorLocation::$4 zp[2]:168 2.00000000000002E14
word~ cursorLocation::$5 zp[2]:166 2.00000000000002E14
byte* cursorLocation::return
byte* cursorLocation::return#0 return zp[2]:166 2.000000000002E12
byte* cursorLocation::return#1 return zp[2]:166 2.775000000000075E13
byte* cursorLocation::return#3 return zp[2]:166 2.0000000000002E13
const word* entries[] = { $78f, $7a4, $7c7, $591, $687, $601, $7c0, $621, $751, $730, $6b8, $791, $71f, $659, $6bf, $714, $6b2, $76c, $793, $78b, $79f, $6dc, $796, $64b, $7bb, $78a, $7cc, $7d0, $608, $6f4, $697, $6e0, $72c, $716, $69b, $719, $7ac, $76b, $629, $60b, $362, $618, $7c4, $641, $7b2, $6ca, $5e3, $683, $73b, $78d, $5eb, $740, $7b1, $744, $709, $7d7, $74a, $708, $6d5, $733, $6af, $5d7, $771, $2fb, $688, $742, $7c3, $5d4, $739, $7c9, $6c9, $752, $67a, $712, $681, $6e8, $79e, $757, $718, $74c, $7cb, $6e3, $6f7, $729, $7b0, $737, $6d4, $6bd, $763, $6db, $11e, $7b8, $7b9, $677, $710, $7c2, $6f3, $745, $7a1, $760, $700, $713, $750, $6fe, $72f, $7c1, $723, $732, $785, $6c7, $663, $71d, $71c, $7b5, $5fb, $6ea, $3b, $736, $78c, $773, $6c2, $3a5, $573, $6d9, $6d7, $169, $5fa, $6f6, $43f, $635, $789, $703, $717, $6c4, $6e5, $755, $6ba, $20e, $6ad, $6fd, $764, $779, $67e, $711, $686, $79b, $72b, $633, $6de, $7be, $7d9, $6dd, $29e, $7bf, $5f4, $756, $704, $7a0, $236, $782, $75a, $74e, $707, $6c3, $6bc, $70d, $7d3, $63c, $61e, $73d, $777, $741, $6cb, $6d0, $65b, $6c1, $6d1, $735, $62e, $75c, $75b, $795, $6e4, $695, $6ff, $72d, $6a1, $6ce, $6f5, $79c, $754, $7c5, $66b, $74f, $772, $6be, $7a6, $5de, $787, $79a }
void gotoxy(byte gotoxy::x , byte gotoxy::y)
byte gotoxy::x
const byte gotoxy::x#1 x = 0
byte gotoxy::y
const byte gotoxy::y#1 y = 0
void main()
word~ main::$21 zp[2]:151 667.3333333333334
word~ main::$22 zp[2]:155 2002.0
word~ main::$34 zp[2]:142 14.428571428571429
word~ main::$35 zp[2]:140 13.931034482758621
word~ main::$41 zp[2]:142 100.1
word~ main::$42 zp[2]:149 85.19148936170212
word~ main::$43 zp[2]:140 108.21621621621621
word*~ main::$47 zp[2]:157 101.0
word*~ main::$48 zp[2]:159 202.0
word*~ main::$49 zp[2]:138 202.0
word*~ main::$50 zp[2]:138 202.0
word*~ main::$51 zp[2]:142 202.0
word*~ main::$52 zp[2]:140 202.0
word*~ main::$53 zp[2]:151 1001.0
word*~ main::$54 zp[2]:153 2002.0
word*~ main::$55 zp[2]:155 2002.0
word*~ main::$56 zp[2]:138 2002.0
word*~ main::$57 zp[2]:138 2002.0
word*~ main::$58 zp[2]:138 2002.0
word*~ main::$59 zp[2]:142 2002.0
word*~ main::$60 zp[2]:140 2002.0
word*~ main::$61 zp[2]:140 2002.0
word~ main::$8 zp[2]:157 202.0
word main::i
word main::i#1 i zp[2]:128 22.0
word main::i#2 i zp[2]:128 5.125
word main::i1
word main::i1#1 i1 zp[2]:130 22.0
word main::i1#2 i1 zp[2]:130 29.228571428571428
word main::j
word main::j#0 j zp[2]:136 22.0
word main::j#1 j zp[2]:136 202.0
word main::j#10 j zp[2]:136 12.285714285714286
word main::j1
word main::j1#0 j1 zp[2]:132 22.0
word main::j1#1 j1 zp[2]:132 202.0
word main::j1#2 j1 zp[2]:132 37.765625
word main::k
word main::k#0 k zp[2]:134 202.0
word main::k#1 k zp[2]:134 2002.0
word main::k#10 k zp[2]:134 85.10000000000001
dword main::mul
dword main::mul#0 mul zp[4]:144 101.0
dword main::mul1
dword main::mul1#0 mul1 zp[4]:144 2002.0
dword main::mul2
dword main::mul2#0 mul2 zp[4]:144 1001.0
word main::num_entries
const word main::num_entries#0 num_entries = $c8*SIZEOF_WORD/SIZEOF_WORD
const byte* main::s[$19] = "looking a+b=2020 within "at
const byte* main::s1[$a] = " entries
"at
const byte* main::s10[7] = "=2020
"at
const byte* main::s11[$c] = "multiplied "at
const byte* main::s2[$1c] = "
looking a+b+c=2020 within "at
const byte* main::s4[2] = "."at
const byte* main::s5[2] = "
"at
const byte* main::s6[$e] = "match found ["at
const byte* main::s7[2] = "]"at
const byte* main::s8[3] = "+["at
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
void* memcpy::destination
void* memcpy::destination#0 destination zp[2]:153 3.333333333336667E11
byte* memcpy::dst
byte* memcpy::dst#1 dst zp[2]:153 1.0E18
byte* memcpy::dst#2 dst zp[2]:153 1.00000333333333325E18
byte* memcpy::dst#4 dst zp[2]:153 2.0000000000002E13
word memcpy::num
const word memcpy::num#0 num = (word)$28*$17
void* memcpy::return
void* memcpy::source
byte* memcpy::source#0 source zp[2]:151 3.333333333336667E11
byte* memcpy::src
byte* memcpy::src#1 src zp[2]:151 2.0E18
byte* memcpy::src#2 src zp[2]:151 1.0000025E18
byte* memcpy::src#4 src zp[2]:151 1.0000000000001E13
byte* memcpy::src_end
byte* memcpy::src_end#0 src_end zp[2]:168 1.2500125E17
void* memset(void* memset::str , byte memset::c , word memset::num)
byte memset::c
byte* memset::dst
byte* memset::dst#1 dst zp[2]:155 2.0E18
byte* memset::dst#2 dst zp[2]:155 1.3333366666666665E18
byte* memset::dst#4 dst zp[2]:155 2.0000000000002E13
byte* memset::end
byte* memset::end#0 end zp[2]:151 1.66668333333333312E17
word memset::num
word memset::num#2 num zp[2]:151 1.0000000000001E13
void* memset::return
void* memset::str
byte* memset::str#0 str zp[2]:155 1.000000000001E12
void* memset::str#3 str zp[2]:155 3.333333333373334E11
void* memset::str#7 str zp[2]:155 22.0
void* memset::str#8 str zp[2]:155 2.000000000002E12
dword mul16u(word mul16u::a , word mul16u::b)
byte~ mul16u::$1 reg byte a 2.00000002E8
word mul16u::a
word mul16u::a#0 a zp[2]:142 1.00000001E8
word mul16u::a#1 a zp[2]:142 67.33333333333333
word mul16u::a#2 a zp[2]:142 667.3333333333334
word mul16u::a#3 a zp[2]:142 667.3333333333334
word mul16u::a#4 a zp[2]:142 6.666833416666667E7
word mul16u::a#7 a zp[2]:142 6052.0
word mul16u::b
word mul16u::b#0 b zp[2]:140 202.0
word mul16u::b#1 b zp[2]:140 2002.0
word mul16u::b#2 b zp[2]:140 2002.0
word mul16u::b#3 b zp[2]:140 2103.0
dword mul16u::mb
dword mul16u::mb#0 mb zp[4]:162 20002.0
dword mul16u::mb#1 mb zp[4]:162 2.00000002E8
dword mul16u::mb#2 mb zp[4]:162 4.2858572E7
dword mul16u::res
dword mul16u::res#1 res zp[4]:144 2.00000002E8
dword mul16u::res#2 res zp[4]:144 3.750026325E7
dword mul16u::res#6 res zp[4]:144 1.00000001E8
dword mul16u::return
dword mul16u::return#2 return zp[4]:144 202.0
dword mul16u::return#3 return zp[4]:144 2002.0
dword mul16u::return#4 return zp[4]:144 2002.0
void newline()
byte* newline::start
byte* newline::start#0 start zp[2]:155 7.5000000000075E11
struct printf_buffer_number printf_buffer loadstore mem[12] = {}
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
struct printf_buffer_number printf_number_buffer::buffer
byte* printf_number_buffer::buffer_digits
byte printf_number_buffer::buffer_sign
byte printf_number_buffer::buffer_sign#0 reg byte a 20002.0
byte printf_number_buffer::buffer_sign#1 reg byte a 20002.0
byte printf_number_buffer::buffer_sign#10 reg byte a 110002.0
struct printf_format_number printf_number_buffer::format
byte printf_number_buffer::format_justify_left
byte printf_number_buffer::format_min_length
byte printf_number_buffer::format_radix
byte printf_number_buffer::format_sign_always
byte printf_number_buffer::format_upper_case
byte printf_number_buffer::format_zero_padding
signed byte printf_number_buffer::len
signed byte printf_number_buffer::padding
void printf_uint(word printf_uint::uvalue , byte printf_uint::format_min_length , byte printf_uint::format_justify_left , byte printf_uint::format_sign_always , byte printf_uint::format_zero_padding , byte printf_uint::format_upper_case , byte printf_uint::format_radix)
struct printf_format_number printf_uint::format
byte printf_uint::format_justify_left
byte printf_uint::format_min_length
byte printf_uint::format_radix
byte printf_uint::format_sign_always
byte printf_uint::format_upper_case
byte printf_uint::format_zero_padding
word printf_uint::uvalue
word printf_uint::uvalue#10 uvalue zp[2]:138 2002.0
word printf_uint::uvalue#11 uvalue zp[2]:138 2002.0
word printf_uint::uvalue#12 uvalue zp[2]:138 8205.5
word printf_uint::uvalue#2 uvalue zp[2]:138 202.0
word printf_uint::uvalue#3 uvalue zp[2]:138 202.0
word printf_uint::uvalue#4 uvalue zp[2]:138 202.0
word printf_uint::uvalue#5 uvalue zp[2]:138 202.0
word printf_uint::uvalue#6 uvalue zp[2]:138 2002.0
word printf_uint::uvalue#7 uvalue zp[2]:138 2002.0
word printf_uint::uvalue#8 uvalue zp[2]:138 2002.0
word printf_uint::uvalue#9 uvalue zp[2]:138 2002.0
void printf_ulong(dword printf_ulong::uvalue , byte printf_ulong::format_min_length , byte printf_ulong::format_justify_left , byte printf_ulong::format_sign_always , byte printf_ulong::format_zero_padding , byte printf_ulong::format_upper_case , byte printf_ulong::format_radix)
struct printf_format_number printf_ulong::format
byte printf_ulong::format_justify_left
byte printf_ulong::format_min_length
byte printf_ulong::format_radix
byte printf_ulong::format_sign_always
byte printf_ulong::format_upper_case
byte printf_ulong::format_zero_padding
dword printf_ulong::uvalue
dword printf_ulong::uvalue#0 uvalue zp[4]:144 202.0
dword printf_ulong::uvalue#1 uvalue zp[4]:144 2002.0
dword printf_ulong::uvalue#2 uvalue zp[4]:144 5551.5
void putchar(byte putchar::code)
byte putchar::code
byte* putchar::loc
byte* putchar::loc#0 loc zp[2]:166 1.000000000001E12
byte putchar::newChar
byte putchar::newChar#0 reg byte a 1.5000000000015E12
const byte* rawmap[$100] = kickasm {{ .var ht = Hashtable().put(0,64, 1,0, 2,32, 3,96) // the table for converting bit 6,7 into ora value
.for(var i=0; i<256; i++) {
.var idx = (i & $60) / 32
.var mask = i & $9f
.byte mask | ht.get(idx)
}
}}
void setcursor()
byte setcursor::c
byte setcursor::c#0 reg byte x 7.50000000000075E12
byte setcursor::c#1 reg byte a 2.0000000000002E13
byte* setcursor::loc
byte* setcursor::loc#0 loc zp[2]:166 1.0000000000001E13
void ultoa(dword ultoa::value , byte* ultoa::buffer , byte ultoa::radix)
byte~ ultoa::$10 reg byte a 2.000000002E9
byte~ ultoa::$11 reg byte a 200002.0
byte* ultoa::buffer
byte* ultoa::buffer#11 buffer zp[2]:155 2.8572857185714287E8
byte* ultoa::buffer#14 buffer zp[2]:155 1.5000000015E9
byte* ultoa::buffer#3 buffer zp[2]:155 200002.0
byte* ultoa::buffer#4 buffer zp[2]:155 2.000000002E9
byte ultoa::digit
byte ultoa::digit#1 digit zp[1]:148 2.000000002E9
byte ultoa::digit#2 digit zp[1]:148 2.85714286E8
dword ultoa::digit_value
dword ultoa::digit_value#0 digit_value zp[4]:162 6.000000005999999E8
dword* ultoa::digit_values
byte ultoa::max_digits
byte ultoa::radix
byte ultoa::started
byte ultoa::started#2 reg byte x 5.000000005E8
byte ultoa::started#4 reg byte x 1.000000001E9
dword ultoa::value
dword ultoa::value#0 value zp[4]:144 1.000000001E9
dword ultoa::value#1 value zp[4]:144 55001.0
dword ultoa::value#2 value zp[4]:144 5.714428578571429E8
dword ultoa::value#6 value zp[4]:144 1.5000000015E9
dword ultoa_append(byte* ultoa_append::buffer , dword ultoa_append::value , dword ultoa_append::sub)
byte* ultoa_append::buffer
byte* ultoa_append::buffer#0 buffer zp[2]:155 1.37500000025E9
byte ultoa_append::digit
byte ultoa_append::digit#1 reg byte x 1.000000000000001E15
byte ultoa_append::digit#2 reg byte x 1.0000050000000015E15
dword ultoa_append::return
dword ultoa_append::return#0 return zp[4]:144 2.000000002E9
dword ultoa_append::sub
dword ultoa_append::sub#0 sub zp[4]:162 3.333335000000005E14
dword ultoa_append::value
dword ultoa_append::value#0 value zp[4]:144 3.666666667333333E9
dword ultoa_append::value#1 value zp[4]:144 2.000000000000002E15
dword ultoa_append::value#2 value zp[4]:144 5.0000183333333425E14
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
byte~ utoa::$10 reg byte a 2.000000002E9
byte~ utoa::$11 reg byte a 200002.0
byte* utoa::buffer
byte* utoa::buffer#11 buffer zp[2]:151 2.8572857185714287E8
byte* utoa::buffer#14 buffer zp[2]:151 1.5000000015E9
byte* utoa::buffer#3 buffer zp[2]:151 200002.0
byte* utoa::buffer#4 buffer zp[2]:151 2.000000002E9
byte utoa::digit
byte utoa::digit#1 digit zp[1]:148 2.000000002E9
byte utoa::digit#2 digit zp[1]:148 2.85714286E8
word utoa::digit_value
word utoa::digit_value#0 digit_value zp[2]:166 6.000000005999999E8
word* utoa::digit_values
byte utoa::max_digits
byte utoa::radix
byte utoa::started
byte utoa::started#2 reg byte x 5.000000005E8
byte utoa::started#4 reg byte x 1.000000001E9
word utoa::value
word utoa::value#0 value zp[2]:138 1.000000001E9
word utoa::value#1 value zp[2]:138 55001.0
word utoa::value#2 value zp[2]:138 5.714428578571429E8
word utoa::value#6 value zp[2]:138 1.5000000015E9
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
byte* utoa_append::buffer
byte* utoa_append::buffer#0 buffer zp[2]:151 1.37500000025E9
byte utoa_append::digit
byte utoa_append::digit#1 reg byte x 1.000000000000001E15
byte utoa_append::digit#2 reg byte x 1.0000050000000015E15
word utoa_append::return
word utoa_append::return#0 return zp[2]:138 2.000000002E9
word utoa_append::sub
word utoa_append::sub#0 sub zp[2]:166 3.333335000000005E14
word utoa_append::value
word utoa_append::value#0 value zp[2]:138 3.666666667333333E9
word utoa_append::value#1 value zp[2]:138 2.000000000000002E15
word utoa_append::value#2 value zp[2]:138 5.0000183333333425E14
zp[2]:128 [ main::i#2 main::i#1 ]
zp[2]:130 [ main::i1#2 main::i1#1 ]
zp[2]:132 [ main::j1#2 main::j1#0 main::j1#1 ]
zp[2]:134 [ main::k#10 main::k#0 main::k#1 ]
zp[2]:136 [ main::j#10 main::j#0 main::j#1 ]
zp[2]:138 [ printf_uint::uvalue#12 printf_uint::uvalue#2 printf_uint::uvalue#3 printf_uint::uvalue#4 printf_uint::uvalue#5 printf_uint::uvalue#6 printf_uint::uvalue#7 printf_uint::uvalue#8 printf_uint::uvalue#9 printf_uint::uvalue#10 printf_uint::uvalue#11 utoa::value#2 utoa::value#6 utoa::value#1 utoa::value#0 main::$56 main::$57 main::$58 main::$49 main::$50 utoa_append::value#2 utoa_append::value#0 utoa_append::value#1 utoa_append::return#0 cputs::s#26 cputs::s#27 cputs::s#0 ]
zp[2]:140 [ mul16u::b#3 mul16u::b#0 mul16u::b#1 mul16u::b#2 main::$60 main::$61 main::$52 main::$43 main::$35 ]
zp[2]:142 [ mul16u::a#4 mul16u::a#7 mul16u::a#1 mul16u::a#2 mul16u::a#3 mul16u::a#0 main::$59 main::$51 main::$41 main::$34 ]
zp[4]:144 [ mul16u::res#2 mul16u::res#6 mul16u::res#1 mul16u::return#3 mul16u::return#4 mul16u::return#2 printf_ulong::uvalue#2 printf_ulong::uvalue#0 printf_ulong::uvalue#1 ultoa::value#2 ultoa::value#6 ultoa::value#1 ultoa::value#0 main::mul2#0 main::mul#0 main::mul1#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ]
reg byte x [ utoa::started#2 utoa::started#4 ]
reg byte a [ printf_number_buffer::buffer_sign#10 printf_number_buffer::buffer_sign#1 printf_number_buffer::buffer_sign#0 ]
zp[1]:148 [ ultoa::digit#2 ultoa::digit#1 utoa::digit#2 utoa::digit#1 ]
reg byte x [ ultoa::started#2 ultoa::started#4 ]
reg byte x [ utoa_append::digit#2 utoa_append::digit#1 ]
reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ]
zp[2]:149 [ main::$42 ]
zp[2]:151 [ main::$53 main::$21 memcpy::src#2 memcpy::src#4 memcpy::src#1 memcpy::source#0 utoa::buffer#11 utoa::buffer#14 utoa::buffer#4 utoa::buffer#3 utoa_append::buffer#0 memset::num#2 memset::end#0 ]
zp[2]:153 [ main::$54 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 memcpy::destination#0 ]
zp[2]:155 [ main::$55 main::$22 ultoa::buffer#11 ultoa::buffer#14 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 memset::str#3 memset::str#7 memset::str#8 memset::dst#2 memset::dst#4 memset::dst#1 memset::str#0 newline::start#0 ]
zp[2]:157 [ main::$47 main::$8 ]
zp[2]:159 [ main::$48 ]
reg byte a [ cputs::c#1 ]
zp[1]:161 [ cputc::c ]
reg byte a [ mul16u::$1 ]
reg byte x [ cputc::convertToScreenCode1_return#0 ]
reg byte a [ utoa::$11 ]
reg byte a [ utoa::$10 ]
reg byte a [ ultoa::$11 ]
reg byte a [ ultoa::$10 ]
zp[4]:162 [ ultoa::digit_value#0 ultoa_append::sub#0 mul16u::mb#2 mul16u::mb#0 mul16u::mb#1 ]
zp[2]:166 [ cursorLocation::return#3 setcursor::loc#0 cursorLocation::return#1 cursorLocation::return#0 putchar::loc#0 cursorLocation::$0 cursorLocation::$1 cursorLocation::$3 cursorLocation::$5 utoa::digit_value#0 utoa_append::sub#0 ]
reg byte x [ setcursor::c#0 ]
reg byte a [ setcursor::c#1 ]
reg byte a [ putchar::newChar#0 ]
zp[2]:168 [ memcpy::src_end#0 cursorLocation::$4 ]
mem[12] [ printf_buffer ]

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,507 @@
void __start()
__start: scope:[__start] from
[0] phi()
to:__start::__init1
__start::__init1: scope:[__start] from __start
[1] conio_cursor_x = 0
[2] conio_cursor_y = 0
[3] conio_line_text = DEFAULT_SCREEN
[4] conio_line_color = COLORRAM
[5] call conio_c64_init
to:__start::@1
__start::@1: scope:[__start] from __start::__init1
[6] phi()
[7] call main
to:__start::@return
__start::@return: scope:[__start] from __start::@1
[8] return
to:@return
void conio_c64_init()
conio_c64_init: scope:[conio_c64_init] from __start::__init1
[9] conio_c64_init::line#0 = *conio_c64_init::BASIC_CURSOR_LINE
[10] if(conio_c64_init::line#0<$19) goto conio_c64_init::@2
to:conio_c64_init::@1
conio_c64_init::@2: scope:[conio_c64_init] from conio_c64_init
[11] phi()
to:conio_c64_init::@1
conio_c64_init::@1: scope:[conio_c64_init] from conio_c64_init conio_c64_init::@2
[12] conio_c64_init::line#2 = phi( conio_c64_init::@2/conio_c64_init::line#0, conio_c64_init/(byte)$19-1 )
[13] gotoxy::y#2 = conio_c64_init::line#2
[14] call gotoxy
to:conio_c64_init::@return
conio_c64_init::@return: scope:[conio_c64_init] from conio_c64_init::@1
[15] return
to:@return
void main()
main: scope:[main] from __start::@1
[16] phi()
[17] call clrscr
to:main::@20
main::@20: scope:[main] from main
[18] main::pwd = passwords
to:main::@1
main::@1: scope:[main] from main::@15 main::@20
[19] main::invalid_b#11 = phi( main::@15/main::invalid_b#30, main::@20/0 )
[19] main::valid_b#11 = phi( main::@15/main::valid_b#28, main::@20/0 )
[19] main::total#10 = phi( main::@15/main::total#1, main::@20/0 )
[19] main::invalid_a#11 = phi( main::@15/main::invalid_a#16, main::@20/0 )
[19] main::valid_a#11 = phi( main::@15/main::valid_a#15, main::@20/0 )
[20] if(0!=*main::pwd) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1
[21] phi()
[22] call cputs
to:main::@23
main::@23: scope:[main] from main::@3
[23] printf_uint::uvalue#0 = main::valid_a#11
[24] call printf_uint
to:main::@24
main::@24: scope:[main] from main::@23
[25] phi()
[26] call cputs
to:main::@25
main::@25: scope:[main] from main::@24
[27] printf_uint::uvalue#1 = main::invalid_a#11
[28] call printf_uint
to:main::@26
main::@26: scope:[main] from main::@25
[29] phi()
[30] call cputs
to:main::@27
main::@27: scope:[main] from main::@26
[31] printf_uint::uvalue#2 = main::total#10
[32] call printf_uint
to:main::@28
main::@28: scope:[main] from main::@27
[33] phi()
[34] call cputs
to:main::@29
main::@29: scope:[main] from main::@28
[35] phi()
[36] call cputs
to:main::@30
main::@30: scope:[main] from main::@29
[37] printf_uint::uvalue#3 = main::valid_b#11
[38] call printf_uint
to:main::@31
main::@31: scope:[main] from main::@30
[39] phi()
[40] call cputs
to:main::@32
main::@32: scope:[main] from main::@31
[41] printf_uint::uvalue#4 = main::invalid_b#11
[42] call printf_uint
to:main::@33
main::@33: scope:[main] from main::@32
[43] phi()
[44] call cputs
to:main::@34
main::@34: scope:[main] from main::@33
[45] printf_uint::uvalue#5 = main::total#10
[46] call printf_uint
to:main::@35
main::@35: scope:[main] from main::@34
[47] phi()
[48] call cputs
to:main::@19
main::@19: scope:[main] from main::@19 main::@35
[49] phi()
to:main::@19
main::@2: scope:[main] from main::@1
[50] strtouc::str#0 = main::pwd
[51] call strtouc
[52] strtouc::return#0 = strtouc::val#3
to:main::@21
main::@21: scope:[main] from main::@2
[53] main::min#0 = strtouc::return#0
[54] main::pwd = ++ main::pwd
[55] strtouc::str#1 = main::pwd
[56] call strtouc
[57] strtouc::return#1 = strtouc::val#3
to:main::@22
main::@22: scope:[main] from main::@21
[58] main::max#0 = strtouc::return#1
[59] main::pwd = ++ main::pwd
[60] main::ch#0 = *main::pwd
[61] main::pwd = main::pwd + 3
[62] main::$5 = main::min#0 - 1
[63] if(main::pwd[main::$5]!=main::ch#0) goto main::@4
to:main::@16
main::@16: scope:[main] from main::@22
[64] phi()
to:main::@4
main::@4: scope:[main] from main::@16 main::@22
[65] main::count_b#4 = phi( main::@16/1, main::@22/0 )
[66] main::$8 = main::max#0 - 1
[67] if(main::pwd[main::$8]!=main::ch#0) goto main::@5
to:main::@17
main::@17: scope:[main] from main::@4
[68] main::count_b#2 = ++ main::count_b#4
to:main::@5
main::@5: scope:[main] from main::@17 main::@4
[69] main::count_b#11 = phi( main::@17/main::count_b#2, main::@4/main::count_b#4 )
to:main::@6
main::@6: scope:[main] from main::@5 main::@9
[70] main::count_a#2 = phi( main::@5/0, main::@9/main::count_a#6 )
[71] if(0!=*main::pwd) goto main::@7
to:main::@8
main::@8: scope:[main] from main::@6
[72] if(main::count_a#2<main::min#0) goto main::@11
to:main::@36
main::@36: scope:[main] from main::@8
[73] if(main::count_a#2<=main::max#0) goto main::@12
to:main::@11
main::@11: scope:[main] from main::@36 main::@8
[74] main::invalid_a#1 = ++ main::invalid_a#11
to:main::@13
main::@13: scope:[main] from main::@11 main::@12
[75] main::invalid_a#16 = phi( main::@11/main::invalid_a#1, main::@12/main::invalid_a#11 )
[75] main::valid_a#15 = phi( main::@11/main::valid_a#11, main::@12/main::valid_a#1 )
[76] if(main::count_b#11==1) goto main::@14
to:main::@18
main::@18: scope:[main] from main::@13
[77] main::invalid_b#1 = ++ main::invalid_b#11
to:main::@15
main::@15: scope:[main] from main::@14 main::@18
[78] main::invalid_b#30 = phi( main::@14/main::invalid_b#11, main::@18/main::invalid_b#1 )
[78] main::valid_b#28 = phi( main::@14/main::valid_b#1, main::@18/main::valid_b#11 )
[79] main::total#1 = ++ main::total#10
[80] main::pwd = ++ main::pwd
to:main::@1
main::@14: scope:[main] from main::@13
[81] main::valid_b#1 = ++ main::valid_b#11
to:main::@15
main::@12: scope:[main] from main::@36
[82] main::valid_a#1 = ++ main::valid_a#11
to:main::@13
main::@7: scope:[main] from main::@6
[83] if(*main::pwd!=main::ch#0) goto main::@9
to:main::@10
main::@10: scope:[main] from main::@7
[84] main::count_a#1 = ++ main::count_a#2
to:main::@9
main::@9: scope:[main] from main::@10 main::@7
[85] main::count_a#6 = phi( main::@10/main::count_a#1, main::@7/main::count_a#2 )
[86] main::pwd = ++ main::pwd
to:main::@6
void gotoxy(byte gotoxy::x , byte gotoxy::y)
gotoxy: scope:[gotoxy] from conio_c64_init::@1
[87] if(gotoxy::y#2<$19+1) goto gotoxy::@3
to:gotoxy::@1
gotoxy::@3: scope:[gotoxy] from gotoxy
[88] phi()
to:gotoxy::@1
gotoxy::@1: scope:[gotoxy] from gotoxy gotoxy::@3
[89] gotoxy::y#4 = phi( gotoxy::@3/gotoxy::y#2, gotoxy/0 )
to:gotoxy::@2
gotoxy::@2: scope:[gotoxy] from gotoxy::@1
[90] conio_cursor_x = gotoxy::x#2
[91] conio_cursor_y = gotoxy::y#4
[92] gotoxy::$7 = (word)gotoxy::y#4
[93] gotoxy::$8 = gotoxy::$7 << 2
[94] gotoxy::$9 = gotoxy::$8 + gotoxy::$7
[95] gotoxy::line_offset#0 = gotoxy::$9 << 3
[96] gotoxy::$5 = DEFAULT_SCREEN + gotoxy::line_offset#0
[97] conio_line_text = gotoxy::$5
[98] gotoxy::$6 = COLORRAM + gotoxy::line_offset#0
[99] conio_line_color = gotoxy::$6
to:gotoxy::@return
gotoxy::@return: scope:[gotoxy] from gotoxy::@2
[100] return
to:@return
void clrscr()
clrscr: scope:[clrscr] from main
[101] phi()
to:clrscr::@1
clrscr::@1: scope:[clrscr] from clrscr clrscr::@5
[102] clrscr::line_cols#5 = phi( clrscr/COLORRAM, clrscr::@5/clrscr::line_cols#1 )
[102] clrscr::line_text#5 = phi( clrscr/DEFAULT_SCREEN, clrscr::@5/clrscr::line_text#1 )
[102] clrscr::l#2 = phi( clrscr/0, clrscr::@5/clrscr::l#1 )
[103] if(clrscr::l#2<$19) goto clrscr::@3
to:clrscr::@2
clrscr::@2: scope:[clrscr] from clrscr::@1
[104] conio_cursor_x = 0
[105] conio_cursor_y = 0
[106] conio_line_text = DEFAULT_SCREEN
[107] conio_line_color = COLORRAM
to:clrscr::@return
clrscr::@return: scope:[clrscr] from clrscr::@2
[108] return
to:@return
clrscr::@3: scope:[clrscr] from clrscr::@1 clrscr::@4
[109] clrscr::c#2 = phi( clrscr::@1/0, clrscr::@4/clrscr::c#1 )
[110] if(clrscr::c#2<$28) goto clrscr::@4
to:clrscr::@5
clrscr::@5: scope:[clrscr] from clrscr::@3
[111] clrscr::line_text#1 = clrscr::line_text#5 + $28
[112] clrscr::line_cols#1 = clrscr::line_cols#5 + $28
[113] clrscr::l#1 = ++ clrscr::l#2
to:clrscr::@1
clrscr::@4: scope:[clrscr] from clrscr::@3
[114] clrscr::line_text#5[clrscr::c#2] = ' '
[115] clrscr::line_cols#5[clrscr::c#2] = LIGHT_BLUE
[116] clrscr::c#1 = ++ clrscr::c#2
to:clrscr::@3
void cputs(to_nomodify byte* cputs::s)
cputs: scope:[cputs] from main::@24 main::@26 main::@28 main::@29 main::@3 main::@31 main::@33 main::@35 printf_number_buffer::@2
[117] cputs::s#11 = phi( main::@24/main::s1, main::@26/main::s2, main::@28/main::s3, main::@29/main::s4, main::@3/main::s, main::@31/main::s1, main::@33/main::s2, main::@35/main::s3, printf_number_buffer::@2/printf_number_buffer::buffer_digits#0 )
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
[118] cputs::s#10 = phi( cputs/cputs::s#11, cputs::@2/cputs::s#0 )
[119] cputs::c#1 = *cputs::s#10
[120] cputs::s#0 = ++ cputs::s#10
[121] if(0!=cputs::c#1) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[122] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[123] cputc::c#0 = cputs::c#1
[124] call cputc
to:cputs::@1
void printf_uint(word printf_uint::uvalue , byte printf_uint::format_min_length , byte printf_uint::format_justify_left , byte printf_uint::format_sign_always , byte printf_uint::format_zero_padding , byte printf_uint::format_upper_case , byte printf_uint::format_radix)
printf_uint: scope:[printf_uint] from main::@23 main::@25 main::@27 main::@30 main::@32 main::@34
[125] printf_uint::uvalue#6 = phi( main::@23/printf_uint::uvalue#0, main::@25/printf_uint::uvalue#1, main::@27/printf_uint::uvalue#2, main::@30/printf_uint::uvalue#3, main::@32/printf_uint::uvalue#4, main::@34/printf_uint::uvalue#5 )
to:printf_uint::@1
printf_uint::@1: scope:[printf_uint] from printf_uint
[126] *((byte*)&printf_buffer) = 0
[127] utoa::value#1 = printf_uint::uvalue#6
[128] call utoa
to:printf_uint::@2
printf_uint::@2: scope:[printf_uint] from printf_uint::@1
[129] printf_number_buffer::buffer_sign#0 = *((byte*)&printf_buffer)
[130] call printf_number_buffer
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint::@2
[131] return
to:@return
byte strtouc(byte* strtouc::str , byte** strtouc::endptr)
strtouc: scope:[strtouc] from main::@2 main::@21
[132] strtouc::str#3 = phi( main::@2/strtouc::str#0, main::@21/strtouc::str#1 )
[133] strtouc::c#0 = *strtouc::str#3
to:strtouc::@1
strtouc::@1: scope:[strtouc] from strtouc strtouc::@2
[134] strtouc::str#4 = phi( strtouc/strtouc::str#3, strtouc::@2/strtouc::str#2 )
[134] strtouc::val#3 = phi( strtouc/0, strtouc::@2/strtouc::val#2 )
[134] strtouc::c#2 = phi( strtouc/strtouc::c#0, strtouc::@2/strtouc::c#1 )
[135] if(strtouc::c#2<'0') goto strtouc::@3
to:strtouc::@4
strtouc::@4: scope:[strtouc] from strtouc::@1
[136] if(strtouc::c#2<='9') goto strtouc::@2
to:strtouc::@3
strtouc::@3: scope:[strtouc] from strtouc::@1 strtouc::@4
[137] *(&main::pwd) = strtouc::str#4
to:strtouc::@return
strtouc::@return: scope:[strtouc] from strtouc::@3
[138] return
to:@return
strtouc::@2: scope:[strtouc] from strtouc::@4
[139] strtouc::$5 = strtouc::val#3 << 2
[140] strtouc::$6 = strtouc::$5 + strtouc::val#3
[141] strtouc::val#1 = strtouc::$6 << 1
[142] strtouc::$4 = strtouc::c#2 - '0'
[143] strtouc::val#2 = strtouc::val#1 + strtouc::$4
[144] strtouc::str#2 = ++ strtouc::str#4
[145] strtouc::c#1 = *strtouc::str#2
to:strtouc::@1
void cputc(byte cputc::c)
cputc: scope:[cputc] from cputs::@2 printf_number_buffer::@3
[146] cputc::c#3 = phi( cputs::@2/cputc::c#0, printf_number_buffer::@3/cputc::c#2 )
[147] if(cputc::c#3=='
') goto cputc::@1
to:cputc::@2
cputc::@2: scope:[cputc] from cputc
[148] conio_line_text[conio_cursor_x] = cputc::c#3
[149] conio_line_color[conio_cursor_x] = LIGHT_BLUE
[150] conio_cursor_x = ++ conio_cursor_x
[151] if(conio_cursor_x!=$28) goto cputc::@return
to:cputc::@3
cputc::@3: scope:[cputc] from cputc::@2
[152] phi()
[153] call cputln
to:cputc::@return
cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@3
[154] return
to:@return
cputc::@1: scope:[cputc] from cputc
[155] phi()
[156] call cputln
to:cputc::@return
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
utoa: scope:[utoa] from printf_uint::@1
[157] phi()
to:utoa::@1
utoa::@1: scope:[utoa] from utoa utoa::@4
[158] utoa::buffer#11 = phi( utoa::@4/utoa::buffer#14, utoa/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[158] utoa::started#2 = phi( utoa::@4/utoa::started#4, utoa/0 )
[158] utoa::value#2 = phi( utoa::@4/utoa::value#6, utoa/utoa::value#1 )
[158] utoa::digit#2 = phi( utoa::@4/utoa::digit#1, utoa/0 )
[159] if(utoa::digit#2<5-1) goto utoa::@2
to:utoa::@3
utoa::@3: scope:[utoa] from utoa::@1
[160] utoa::$11 = (byte)utoa::value#2
[161] *utoa::buffer#11 = DIGITS[utoa::$11]
[162] utoa::buffer#3 = ++ utoa::buffer#11
[163] *utoa::buffer#3 = 0
to:utoa::@return
utoa::@return: scope:[utoa] from utoa::@3
[164] return
to:@return
utoa::@2: scope:[utoa] from utoa::@1
[165] utoa::$10 = utoa::digit#2 << 1
[166] utoa::digit_value#0 = RADIX_DECIMAL_VALUES[utoa::$10]
[167] if(0!=utoa::started#2) goto utoa::@5
to:utoa::@7
utoa::@7: scope:[utoa] from utoa::@2
[168] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5
to:utoa::@4
utoa::@4: scope:[utoa] from utoa::@6 utoa::@7
[169] utoa::buffer#14 = phi( utoa::@7/utoa::buffer#11, utoa::@6/utoa::buffer#4 )
[169] utoa::started#4 = phi( utoa::@7/utoa::started#2, utoa::@6/1 )
[169] utoa::value#6 = phi( utoa::@7/utoa::value#2, utoa::@6/utoa::value#0 )
[170] utoa::digit#1 = ++ utoa::digit#2
to:utoa::@1
utoa::@5: scope:[utoa] from utoa::@2 utoa::@7
[171] utoa_append::buffer#0 = utoa::buffer#11
[172] utoa_append::value#0 = utoa::value#2
[173] utoa_append::sub#0 = utoa::digit_value#0
[174] call utoa_append
[175] utoa_append::return#0 = utoa_append::value#2
to:utoa::@6
utoa::@6: scope:[utoa] from utoa::@5
[176] utoa::value#0 = utoa_append::return#0
[177] utoa::buffer#4 = ++ utoa::buffer#11
to:utoa::@4
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
printf_number_buffer: scope:[printf_number_buffer] from printf_uint::@2
[178] phi()
to:printf_number_buffer::@1
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer
[179] if(0==printf_number_buffer::buffer_sign#0) goto printf_number_buffer::@2
to:printf_number_buffer::@3
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@1
[180] cputc::c#2 = printf_number_buffer::buffer_sign#0
[181] call cputc
to:printf_number_buffer::@2
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@3
[182] phi()
[183] call cputs
to:printf_number_buffer::@return
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@2
[184] return
to:@return
void cputln()
cputln: scope:[cputln] from cputc::@1 cputc::@3
[185] conio_line_text = conio_line_text + $28
[186] conio_line_color = conio_line_color + $28
[187] conio_cursor_x = 0
[188] conio_cursor_y = ++ conio_cursor_y
[189] call cscroll
to:cputln::@return
cputln::@return: scope:[cputln] from cputln
[190] return
to:@return
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
utoa_append: scope:[utoa_append] from utoa::@5
[191] phi()
to:utoa_append::@1
utoa_append::@1: scope:[utoa_append] from utoa_append utoa_append::@2
[192] utoa_append::digit#2 = phi( utoa_append/0, utoa_append::@2/utoa_append::digit#1 )
[192] utoa_append::value#2 = phi( utoa_append/utoa_append::value#0, utoa_append::@2/utoa_append::value#1 )
[193] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2
to:utoa_append::@3
utoa_append::@3: scope:[utoa_append] from utoa_append::@1
[194] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2]
to:utoa_append::@return
utoa_append::@return: scope:[utoa_append] from utoa_append::@3
[195] return
to:@return
utoa_append::@2: scope:[utoa_append] from utoa_append::@1
[196] utoa_append::digit#1 = ++ utoa_append::digit#2
[197] utoa_append::value#1 = utoa_append::value#2 - utoa_append::sub#0
to:utoa_append::@1
void cscroll()
cscroll: scope:[cscroll] from cputln
[198] if(conio_cursor_y!=$19) goto cscroll::@return
to:cscroll::@1
cscroll::@1: scope:[cscroll] from cscroll
[199] phi()
[200] call memcpy
to:cscroll::@2
cscroll::@2: scope:[cscroll] from cscroll::@1
[201] phi()
[202] call memcpy
to:cscroll::@3
cscroll::@3: scope:[cscroll] from cscroll::@2
[203] phi()
[204] call memset
to:cscroll::@4
cscroll::@4: scope:[cscroll] from cscroll::@3
[205] phi()
[206] call memset
to:cscroll::@5
cscroll::@5: scope:[cscroll] from cscroll::@4
[207] conio_line_text = conio_line_text - $28
[208] conio_line_color = conio_line_color - $28
[209] conio_cursor_y = -- conio_cursor_y
to:cscroll::@return
cscroll::@return: scope:[cscroll] from cscroll cscroll::@5
[210] return
to:@return
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
memcpy: scope:[memcpy] from cscroll::@1 cscroll::@2
[211] memcpy::destination#2 = phi( cscroll::@1/(void*)DEFAULT_SCREEN, cscroll::@2/(void*)COLORRAM )
[211] memcpy::source#2 = phi( cscroll::@1/(void*)DEFAULT_SCREEN+$28, cscroll::@2/(void*)COLORRAM+$28 )
[212] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28
[213] memcpy::src#4 = (byte*)memcpy::source#2
[214] memcpy::dst#4 = (byte*)memcpy::destination#2
to:memcpy::@1
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
[215] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
[215] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
[216] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
to:memcpy::@return
memcpy::@return: scope:[memcpy] from memcpy::@1
[217] return
to:@return
memcpy::@2: scope:[memcpy] from memcpy::@1
[218] *memcpy::dst#2 = *memcpy::src#2
[219] memcpy::dst#1 = ++ memcpy::dst#2
[220] memcpy::src#1 = ++ memcpy::src#2
to:memcpy::@1
void* memset(void* memset::str , byte memset::c , word memset::num)
memset: scope:[memset] from cscroll::@3 cscroll::@4
[221] memset::c#4 = phi( cscroll::@3/' ', cscroll::@4/LIGHT_BLUE )
[221] memset::str#3 = phi( cscroll::@3/(void*)DEFAULT_SCREEN+(word)$19*$28-$28, cscroll::@4/(void*)COLORRAM+(word)$19*$28-$28 )
to:memset::@1
memset::@1: scope:[memset] from memset
[222] memset::end#0 = (byte*)memset::str#3 + $28
[223] memset::dst#4 = (byte*)memset::str#3
to:memset::@2
memset::@2: scope:[memset] from memset::@1 memset::@3
[224] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 )
[225] if(memset::dst#2!=memset::end#0) goto memset::@3
to:memset::@return
memset::@return: scope:[memset] from memset::@2
[226] return
to:@return
memset::@3: scope:[memset] from memset::@2
[227] *memset::dst#2 = memset::c#4
[228] memset::dst#1 = ++ memset::dst#2
to:memset::@2

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,464 @@
void main()
main: scope:[main] from
[0] phi()
[1] call clrscr
to:main::@2
main::@2: scope:[main] from main
[2] phi()
[3] call test_slope
[4] test_slope::return#0 = test_slope::trees#2
to:main::@3
main::@3: scope:[main] from main::@2
[5] printf_uint::uvalue#0 = test_slope::return#0
[6] call cputs
to:main::@4
main::@4: scope:[main] from main::@3
[7] phi()
[8] call printf_uint
to:main::@5
main::@5: scope:[main] from main::@4
[9] phi()
[10] call cputs
to:main::@6
main::@6: scope:[main] from main::@5
[11] phi()
[12] call test_slope
[13] test_slope::return#1 = test_slope::trees#2
to:main::@7
main::@7: scope:[main] from main::@6
[14] printf_uint::uvalue#1 = test_slope::return#1
[15] call cputs
to:main::@8
main::@8: scope:[main] from main::@7
[16] phi()
[17] call printf_uint
to:main::@9
main::@9: scope:[main] from main::@8
[18] phi()
[19] call cputs
to:main::@10
main::@10: scope:[main] from main::@9
[20] phi()
[21] call test_slope
[22] test_slope::return#10 = test_slope::trees#2
to:main::@11
main::@11: scope:[main] from main::@10
[23] printf_uint::uvalue#2 = test_slope::return#10
[24] call cputs
to:main::@12
main::@12: scope:[main] from main::@11
[25] phi()
[26] call printf_uint
to:main::@13
main::@13: scope:[main] from main::@12
[27] phi()
[28] call cputs
to:main::@14
main::@14: scope:[main] from main::@13
[29] phi()
[30] call test_slope
[31] test_slope::return#11 = test_slope::trees#2
to:main::@15
main::@15: scope:[main] from main::@14
[32] printf_uint::uvalue#3 = test_slope::return#11
[33] call cputs
to:main::@16
main::@16: scope:[main] from main::@15
[34] phi()
[35] call printf_uint
to:main::@17
main::@17: scope:[main] from main::@16
[36] phi()
[37] call cputs
to:main::@18
main::@18: scope:[main] from main::@17
[38] phi()
[39] call test_slope
[40] test_slope::return#12 = test_slope::trees#2
to:main::@19
main::@19: scope:[main] from main::@18
[41] printf_uint::uvalue#4 = test_slope::return#12
[42] call cputs
to:main::@20
main::@20: scope:[main] from main::@19
[43] phi()
[44] call printf_uint
to:main::@21
main::@21: scope:[main] from main::@20
[45] phi()
[46] call cputs
to:main::@22
main::@22: scope:[main] from main::@21
[47] phi()
[48] call test_slope
[49] test_slope::return#13 = test_slope::trees#2
to:main::@23
main::@23: scope:[main] from main::@22
[50] printf_uint::uvalue#5 = test_slope::return#13
[51] call cputs
to:main::@24
main::@24: scope:[main] from main::@23
[52] phi()
[53] call printf_uint
to:main::@25
main::@25: scope:[main] from main::@24
[54] phi()
[55] call cputs
to:main::@1
main::@1: scope:[main] from main::@1 main::@25
[56] phi()
to:main::@1
void clrscr()
clrscr: scope:[clrscr] from main
[57] memset::str#7 = (void*)*SAVMSC
[58] call memset
to:clrscr::@1
clrscr::@1: scope:[clrscr] from clrscr
[59] *OLDCHR = 0
[60] call gotoxy
to:clrscr::@return
clrscr::@return: scope:[clrscr] from clrscr::@1
[61] return
to:@return
word test_slope(byte test_slope::x_inc , byte test_slope::y_inc)
test_slope: scope:[test_slope] from main::@10 main::@14 main::@18 main::@2 main::@22 main::@6
[62] test_slope::y_inc#12 = phi( main::@10/1, main::@14/1, main::@18/1, main::@2/1, main::@22/2, main::@6/1 )
[62] test_slope::x_inc#10 = phi( main::@10/3, main::@14/5, main::@18/7, main::@2/3, main::@22/1, main::@6/1 )
to:test_slope::@1
test_slope::@1: scope:[test_slope] from test_slope test_slope::@4
[63] test_slope::trees#2 = phi( test_slope/0, test_slope::@4/test_slope::trees#6 )
[63] test_slope::x#3 = phi( test_slope/0, test_slope::@4/test_slope::x#8 )
[63] test_slope::mapline#2 = phi( test_slope/map, test_slope::@4/test_slope::mapline#1 )
[63] test_slope::y#2 = phi( test_slope/0, test_slope::@4/test_slope::y#1 )
[64] if(test_slope::y#2<$143) goto test_slope::@2
to:test_slope::@return
test_slope::@return: scope:[test_slope] from test_slope::@1
[65] return
to:@return
test_slope::@2: scope:[test_slope] from test_slope::@1
[66] if(test_slope::mapline#2[test_slope::x#3]!='#'at) goto test_slope::@3
to:test_slope::@5
test_slope::@5: scope:[test_slope] from test_slope::@2
[67] test_slope::trees#1 = ++ test_slope::trees#2
to:test_slope::@3
test_slope::@3: scope:[test_slope] from test_slope::@2 test_slope::@5
[68] test_slope::trees#6 = phi( test_slope::@2/test_slope::trees#2, test_slope::@5/test_slope::trees#1 )
[69] test_slope::x#1 = test_slope::x#3 + test_slope::x_inc#10
[70] if(test_slope::x#1<$1f) goto test_slope::@4
to:test_slope::@6
test_slope::@6: scope:[test_slope] from test_slope::@3
[71] test_slope::x#2 = test_slope::x#1 - $1f
to:test_slope::@4
test_slope::@4: scope:[test_slope] from test_slope::@3 test_slope::@6
[72] test_slope::x#8 = phi( test_slope::@3/test_slope::x#1, test_slope::@6/test_slope::x#2 )
[73] test_slope::$6 = test_slope::y_inc#12 << 1
[74] test_slope::$7 = test_slope::$6 + test_slope::y_inc#12
[75] test_slope::$8 = test_slope::$7 << 1
[76] test_slope::$9 = test_slope::$8 + test_slope::y_inc#12
[77] test_slope::$10 = test_slope::$9 << 1
[78] test_slope::$11 = test_slope::$10 + test_slope::y_inc#12
[79] test_slope::$12 = test_slope::$11 << 1
[80] test_slope::$5 = test_slope::$12 + test_slope::y_inc#12
[81] test_slope::mapline#1 = test_slope::mapline#2 + test_slope::$5
[82] test_slope::y#1 = test_slope::y#2 + test_slope::y_inc#12
to:test_slope::@1
void cputs(to_nomodify byte* cputs::s)
cputs: scope:[cputs] from main::@11 main::@13 main::@15 main::@17 main::@19 main::@21 main::@23 main::@25 main::@3 main::@5 main::@7 main::@9 printf_number_buffer::@2
[83] cputs::s#15 = phi( main::@11/main::s4, main::@13/main::s1, main::@15/main::s6, main::@17/main::s1, main::@19/main::s8, main::@21/main::s1, main::@23/main::s10, main::@25/main::s1, main::@3/main::s, main::@5/main::s1, main::@7/main::s2, main::@9/main::s1, printf_number_buffer::@2/printf_number_buffer::buffer_digits#0 )
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
[84] cputs::s#14 = phi( cputs/cputs::s#15, cputs::@2/cputs::s#0 )
[85] cputs::c#1 = *cputs::s#14
[86] cputs::s#0 = ++ cputs::s#14
[87] if(0!=cputs::c#1) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[88] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[89] cputc::c = cputs::c#1
[90] call cputc
to:cputs::@1
void printf_uint(word printf_uint::uvalue , byte printf_uint::format_min_length , byte printf_uint::format_justify_left , byte printf_uint::format_sign_always , byte printf_uint::format_zero_padding , byte printf_uint::format_upper_case , byte printf_uint::format_radix)
printf_uint: scope:[printf_uint] from main::@12 main::@16 main::@20 main::@24 main::@4 main::@8
[91] printf_uint::uvalue#6 = phi( main::@12/printf_uint::uvalue#2, main::@16/printf_uint::uvalue#3, main::@20/printf_uint::uvalue#4, main::@24/printf_uint::uvalue#5, main::@4/printf_uint::uvalue#0, main::@8/printf_uint::uvalue#1 )
to:printf_uint::@1
printf_uint::@1: scope:[printf_uint] from printf_uint
[92] *((byte*)&printf_buffer) = 0
[93] utoa::value#1 = printf_uint::uvalue#6
[94] call utoa
to:printf_uint::@2
printf_uint::@2: scope:[printf_uint] from printf_uint::@1
[95] printf_number_buffer::buffer_sign#0 = *((byte*)&printf_buffer)
[96] call printf_number_buffer
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint::@2
[97] return
to:@return
void* memset(void* memset::str , byte memset::c , word memset::num)
memset: scope:[memset] from clrscr newline::@4
[98] memset::str#3 = phi( clrscr/memset::str#7, newline::@4/memset::str#8 )
[98] memset::num#2 = phi( clrscr/(word)$28*$18, newline::@4/$28 )
[99] if(memset::num#2<=0) goto memset::@return
to:memset::@1
memset::@1: scope:[memset] from memset
[100] memset::end#0 = (byte*)memset::str#3 + memset::num#2
[101] memset::dst#4 = (byte*)memset::str#3
to:memset::@2
memset::@2: scope:[memset] from memset::@1 memset::@3
[102] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 )
[103] if(memset::dst#2!=memset::end#0) goto memset::@3
to:memset::@return
memset::@return: scope:[memset] from memset memset::@2
[104] return
to:@return
memset::@3: scope:[memset] from memset::@2
[105] *memset::dst#2 = 0
[106] memset::dst#1 = ++ memset::dst#2
to:memset::@2
void gotoxy(byte gotoxy::x , byte gotoxy::y)
gotoxy: scope:[gotoxy] from clrscr::@1
[107] *COLCRS = gotoxy::x#1
[108] *ROWCRS = gotoxy::y#1
[109] call setcursor
to:gotoxy::@return
gotoxy::@return: scope:[gotoxy] from gotoxy
[110] return
to:@return
void cputc(volatile byte cputc::c)
cputc: scope:[cputc] from cputs::@2 printf_number_buffer::@3
[111] if(cputc::c==' 'at) goto cputc::@1
to:cputc::@3
cputc::@3: scope:[cputc] from cputc
[112] if(cputc::c=='
'at) goto cputc::@2
to:cputc::@8
cputc::@8: scope:[cputc] from cputc::@3
[113] if(cputc::c==$9b) goto cputc::@2
to:cputc::convertToScreenCode1
cputc::convertToScreenCode1: scope:[cputc] from cputc::@8
[114] cputc::convertToScreenCode1_return#0 = rawmap[*cputc::convertToScreenCode1_v#0]
to:cputc::@6
cputc::@6: scope:[cputc] from cputc::convertToScreenCode1
[115] phi()
[116] call putchar
to:cputc::@7
cputc::@7: scope:[cputc] from cputc::@6
[117] *COLCRS = ++ *COLCRS
[118] if(*COLCRS==$28) goto cputc::@5
to:cputc::@4
cputc::@4: scope:[cputc] from cputc::@7
[119] phi()
[120] call setcursor
to:cputc::@return
cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@4 cputc::@5
[121] return
to:@return
cputc::@5: scope:[cputc] from cputc::@7
[122] *COLCRS = 0
[123] call newline
to:cputc::@return
cputc::@2: scope:[cputc] from cputc::@3 cputc::@8
[124] *COLCRS = 0
[125] call newline
to:cputc::@return
cputc::@1: scope:[cputc] from cputc
[126] *COLCRS = 0
[127] call setcursor
to:cputc::@return
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
utoa: scope:[utoa] from printf_uint::@1
[128] phi()
to:utoa::@1
utoa::@1: scope:[utoa] from utoa utoa::@4
[129] utoa::buffer#11 = phi( utoa::@4/utoa::buffer#14, utoa/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[129] utoa::started#2 = phi( utoa::@4/utoa::started#4, utoa/0 )
[129] utoa::value#2 = phi( utoa::@4/utoa::value#6, utoa/utoa::value#1 )
[129] utoa::digit#2 = phi( utoa::@4/utoa::digit#1, utoa/0 )
[130] if(utoa::digit#2<5-1) goto utoa::@2
to:utoa::@3
utoa::@3: scope:[utoa] from utoa::@1
[131] utoa::$11 = (byte)utoa::value#2
[132] *utoa::buffer#11 = DIGITS[utoa::$11]
[133] utoa::buffer#3 = ++ utoa::buffer#11
[134] *utoa::buffer#3 = 0
to:utoa::@return
utoa::@return: scope:[utoa] from utoa::@3
[135] return
to:@return
utoa::@2: scope:[utoa] from utoa::@1
[136] utoa::$10 = utoa::digit#2 << 1
[137] utoa::digit_value#0 = RADIX_DECIMAL_VALUES[utoa::$10]
[138] if(0!=utoa::started#2) goto utoa::@5
to:utoa::@7
utoa::@7: scope:[utoa] from utoa::@2
[139] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5
to:utoa::@4
utoa::@4: scope:[utoa] from utoa::@6 utoa::@7
[140] utoa::buffer#14 = phi( utoa::@7/utoa::buffer#11, utoa::@6/utoa::buffer#4 )
[140] utoa::started#4 = phi( utoa::@7/utoa::started#2, utoa::@6/1 )
[140] utoa::value#6 = phi( utoa::@7/utoa::value#2, utoa::@6/utoa::value#0 )
[141] utoa::digit#1 = ++ utoa::digit#2
to:utoa::@1
utoa::@5: scope:[utoa] from utoa::@2 utoa::@7
[142] utoa_append::buffer#0 = utoa::buffer#11
[143] utoa_append::value#0 = utoa::value#2
[144] utoa_append::sub#0 = utoa::digit_value#0
[145] call utoa_append
[146] utoa_append::return#0 = utoa_append::value#2
to:utoa::@6
utoa::@6: scope:[utoa] from utoa::@5
[147] utoa::value#0 = utoa_append::return#0
[148] utoa::buffer#4 = ++ utoa::buffer#11
to:utoa::@4
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
printf_number_buffer: scope:[printf_number_buffer] from printf_uint::@2
[149] phi()
to:printf_number_buffer::@1
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer
[150] if(0==printf_number_buffer::buffer_sign#0) goto printf_number_buffer::@2
to:printf_number_buffer::@3
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@1
[151] cputc::c = printf_number_buffer::buffer_sign#0
[152] call cputc
to:printf_number_buffer::@2
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@3
[153] phi()
[154] call cputs
to:printf_number_buffer::@return
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@2
[155] return
to:@return
void setcursor()
setcursor: scope:[setcursor] from cputc::@1 cputc::@4 gotoxy newline::@1 putchar::@1
[156] *(*OLDADR) = *OLDCHR
[157] call cursorLocation
[158] cursorLocation::return#3 = cursorLocation::return#1
to:setcursor::@3
setcursor::@3: scope:[setcursor] from setcursor
[159] setcursor::loc#0 = cursorLocation::return#3
[160] setcursor::c#0 = *setcursor::loc#0
[161] *OLDCHR = setcursor::c#0
[162] *OLDADR = setcursor::loc#0
to:setcursor::@2
setcursor::@2: scope:[setcursor] from setcursor::@3
[163] *CRSINH = 0
[164] setcursor::c#1 = setcursor::c#0 ^ $80
to:setcursor::@1
setcursor::@1: scope:[setcursor] from setcursor::@2
[165] *(*OLDADR) = setcursor::c#1
to:setcursor::@return
setcursor::@return: scope:[setcursor] from setcursor::@1
[166] return
to:@return
void putchar(byte putchar::code)
putchar: scope:[putchar] from cputc::@6
[167] *(*OLDADR) = *OLDCHR
[168] call cursorLocation
[169] cursorLocation::return#0 = cursorLocation::return#1
to:putchar::@1
putchar::@1: scope:[putchar] from putchar
[170] putchar::loc#0 = cursorLocation::return#0
[171] putchar::newChar#0 = cputc::convertToScreenCode1_return#0
[172] *putchar::loc#0 = putchar::newChar#0
[173] *OLDCHR = putchar::newChar#0
[174] call setcursor
to:putchar::@return
putchar::@return: scope:[putchar] from putchar::@1
[175] return
to:@return
void newline()
newline: scope:[newline] from cputc::@2 cputc::@5
[176] *ROWCRS = ++ *ROWCRS
[177] if(*ROWCRS!=$18) goto newline::@1
to:newline::@3
newline::@3: scope:[newline] from newline
[178] *(*OLDADR) = *(*OLDADR) ^ $80
to:newline::@2
newline::@2: scope:[newline] from newline::@3
[179] newline::start#0 = *SAVMSC
[180] memcpy::source#0 = newline::start#0 + $28
[181] memcpy::destination#0 = (void*)newline::start#0
[182] call memcpy
to:newline::@4
newline::@4: scope:[newline] from newline::@2
[183] memset::str#0 = newline::start#0 + (word)$28*$17
[184] memset::str#8 = (void*)memset::str#0
[185] call memset
to:newline::@5
newline::@5: scope:[newline] from newline::@4
[186] *ROWCRS = (byte)$18-1
to:newline::@1
newline::@1: scope:[newline] from newline newline::@5
[187] phi()
[188] call setcursor
to:newline::@return
newline::@return: scope:[newline] from newline::@1
[189] return
to:@return
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
utoa_append: scope:[utoa_append] from utoa::@5
[190] phi()
to:utoa_append::@1
utoa_append::@1: scope:[utoa_append] from utoa_append utoa_append::@2
[191] utoa_append::digit#2 = phi( utoa_append/0, utoa_append::@2/utoa_append::digit#1 )
[191] utoa_append::value#2 = phi( utoa_append/utoa_append::value#0, utoa_append::@2/utoa_append::value#1 )
[192] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2
to:utoa_append::@3
utoa_append::@3: scope:[utoa_append] from utoa_append::@1
[193] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2]
to:utoa_append::@return
utoa_append::@return: scope:[utoa_append] from utoa_append::@3
[194] return
to:@return
utoa_append::@2: scope:[utoa_append] from utoa_append::@1
[195] utoa_append::digit#1 = ++ utoa_append::digit#2
[196] utoa_append::value#1 = utoa_append::value#2 - utoa_append::sub#0
to:utoa_append::@1
byte* cursorLocation()
cursorLocation: scope:[cursorLocation] from putchar setcursor
[197] cursorLocation::$3 = (word)*ROWCRS
[198] cursorLocation::$4 = cursorLocation::$3 << 2
[199] cursorLocation::$5 = cursorLocation::$4 + cursorLocation::$3
[200] cursorLocation::$0 = cursorLocation::$5 << 3
[201] cursorLocation::$1 = *SAVMSC + cursorLocation::$0
[202] cursorLocation::return#1 = cursorLocation::$1 + *COLCRS
to:cursorLocation::@return
cursorLocation::@return: scope:[cursorLocation] from cursorLocation
[203] return
to:@return
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
memcpy: scope:[memcpy] from newline::@2
[204] memcpy::src_end#0 = (byte*)(void*)memcpy::source#0 + memcpy::num#0
[205] memcpy::src#4 = (byte*)(void*)memcpy::source#0
[206] memcpy::dst#4 = (byte*)memcpy::destination#0
to:memcpy::@1
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
[207] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
[207] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
[208] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
to:memcpy::@return
memcpy::@return: scope:[memcpy] from memcpy::@1
[209] return
to:@return
memcpy::@2: scope:[memcpy] from memcpy::@1
[210] *memcpy::dst#2 = *memcpy::src#2
[211] memcpy::dst#1 = ++ memcpy::dst#2
[212] memcpy::src#1 = ++ memcpy::src#2
to:memcpy::@1

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,441 @@
void main()
main: scope:[main] from
[0] phi()
[1] call clrscr
to:main::@1
main::@1: scope:[main] from main main::@12 main::@22 main::@24 main::@25 main::@32 main::@33
[2] main::total#10 = phi( main::@12/main::total#1, main::@22/main::total#10, main::@24/main::total#10, main::@25/main::total#10, main/0 )
[2] main::valid#10 = phi( main::@12/main::valid#8, main::@22/main::valid#10, main::@24/main::valid#10, main::@25/main::valid#10, main/0 )
[2] main::pass#10 = phi( main::@12/main::pass#3, main::@22/main::pass#14, main::@24/main::pass#1, main::@25/main::pass#11, main/passports )
[3] if(0!=*main::pass#10) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1
[4] phi()
[5] call cputs
to:main::@28
main::@28: scope:[main] from main::@3
[6] printf_uint::uvalue#0 = main::valid#10
[7] call printf_uint
to:main::@29
main::@29: scope:[main] from main::@28
[8] phi()
[9] call cputs
to:main::@30
main::@30: scope:[main] from main::@29
[10] printf_uint::uvalue#1 = main::total#10
[11] call printf_uint
to:main::@31
main::@31: scope:[main] from main::@30
[12] phi()
[13] call cputs
to:main::@27
main::@27: scope:[main] from main::@27 main::@31
[14] phi()
to:main::@27
main::@2: scope:[main] from main::@1
[15] if(*main::pass#10!=' 'at) goto main::@4
to:main::@24
main::@24: scope:[main] from main::@2
[16] main::pass#1 = ++ main::pass#10
to:main::@1
main::@4: scope:[main] from main::@2
[17] if(*main::pass#10!='
'at) goto main::@13
to:main::@25
main::@25: scope:[main] from main::@4
[18] main::pass#11 = ++ main::pass#10
[19] if(*main::pass#11!='
'at) goto main::@1
to:main::@26
main::@26: scope:[main] from main::@25
[20] main::pass#3 = ++ main::pass#11
to:main::@5
main::@5: scope:[main] from main::@26 main::@8
[21] main::num_found#2 = phi( main::@26/0, main::@8/main::num_found#6 )
[21] main::i#2 = phi( main::@26/0, main::@8/main::i#1 )
[22] if(main::i#2<7) goto main::@6
to:main::@7
main::@7: scope:[main] from main::@5
[23] if(main::num_found#2==7) goto main::@11
to:main::@10
main::@10: scope:[main] from main::@7
[24] phi()
[25] call cputs
to:main::@12
main::@12: scope:[main] from main::@10 main::@11
[26] main::valid#8 = phi( main::@11/main::valid#1, main::@10/main::valid#10 )
[27] main::total#1 = ++ main::total#10
to:main::@1
main::@11: scope:[main] from main::@7
[28] main::valid#1 = ++ main::valid#10
[29] call cputs
to:main::@12
main::@6: scope:[main] from main::@5
[30] if(0==main::tags_found[main::i#2]) goto main::@8
to:main::@9
main::@9: scope:[main] from main::@6
[31] main::num_found#1 = ++ main::num_found#2
to:main::@8
main::@8: scope:[main] from main::@6 main::@9
[32] main::num_found#6 = phi( main::@9/main::num_found#1, main::@6/main::num_found#2 )
[33] main::tags_found[main::i#2] = 0
[34] main::i#1 = ++ main::i#2
to:main::@5
main::@13: scope:[main] from main::@20 main::@4
[35] main::required_tag#6 = phi( main::@20/main::required_tag#1, main::@4/required_tags )
[35] main::tag_idx#2 = phi( main::@20/main::tag_idx#1, main::@4/0 )
[36] if(main::tag_idx#2<7) goto main::@14
to:main::@21
main::@21: scope:[main] from main::@13 main::@19
[37] main::pass#4 = main::pass#10 + 3
to:main::@22
main::@22: scope:[main] from main::@21 main::@23
[38] main::pass#14 = phi( main::@21/main::pass#4, main::@23/main::pass#5 )
[39] if(0==*main::pass#14) goto main::@1
to:main::@33
main::@33: scope:[main] from main::@22
[40] if(*main::pass#14==' 'at) goto main::@1
to:main::@32
main::@32: scope:[main] from main::@33
[41] if(*main::pass#14!='
'at) goto main::@23
to:main::@1
main::@23: scope:[main] from main::@32
[42] main::pass#5 = ++ main::pass#14
to:main::@22
main::@14: scope:[main] from main::@13 main::@17
[43] main::match#2 = phi( main::@13/0, main::@17/main::match#6 )
[43] main::i1#2 = phi( main::@13/0, main::@17/main::i1#1 )
[44] if(main::i1#2<3) goto main::@15
to:main::@16
main::@16: scope:[main] from main::@14
[45] if(main::match#2!=3) goto main::@20
to:main::@19
main::@19: scope:[main] from main::@16
[46] main::tags_found[main::tag_idx#2] = 1
to:main::@21
main::@20: scope:[main] from main::@16
[47] main::required_tag#1 = main::required_tag#6 + 3
[48] main::tag_idx#1 = ++ main::tag_idx#2
to:main::@13
main::@15: scope:[main] from main::@14
[49] if(main::required_tag#6[main::i1#2]!=main::pass#10[main::i1#2]) goto main::@17
to:main::@18
main::@18: scope:[main] from main::@15
[50] main::match#1 = ++ main::match#2
to:main::@17
main::@17: scope:[main] from main::@15 main::@18
[51] main::match#6 = phi( main::@15/main::match#2, main::@18/main::match#1 )
[52] main::i1#1 = ++ main::i1#2
to:main::@14
void clrscr()
clrscr: scope:[clrscr] from main
[53] memset::str#7 = (void*)*SAVMSC
[54] call memset
to:clrscr::@1
clrscr::@1: scope:[clrscr] from clrscr
[55] *OLDCHR = 0
[56] call gotoxy
to:clrscr::@return
clrscr::@return: scope:[clrscr] from clrscr::@1
[57] return
to:@return
void cputs(to_nomodify byte* cputs::s)
cputs: scope:[cputs] from main::@10 main::@11 main::@29 main::@3 main::@31 printf_number_buffer::@2
[58] cputs::s#8 = phi( main::@10/main::s4, main::@11/main::s3, main::@3/main::s, main::@29/main::s1, main::@31/main::s2, printf_number_buffer::@2/printf_number_buffer::buffer_digits#0 )
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
[59] cputs::s#7 = phi( cputs/cputs::s#8, cputs::@2/cputs::s#0 )
[60] cputs::c#1 = *cputs::s#7
[61] cputs::s#0 = ++ cputs::s#7
[62] if(0!=cputs::c#1) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[63] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[64] cputc::c = cputs::c#1
[65] call cputc
to:cputs::@1
void printf_uint(word printf_uint::uvalue , byte printf_uint::format_min_length , byte printf_uint::format_justify_left , byte printf_uint::format_sign_always , byte printf_uint::format_zero_padding , byte printf_uint::format_upper_case , byte printf_uint::format_radix)
printf_uint: scope:[printf_uint] from main::@28 main::@30
[66] printf_uint::uvalue#2 = phi( main::@28/printf_uint::uvalue#0, main::@30/printf_uint::uvalue#1 )
to:printf_uint::@1
printf_uint::@1: scope:[printf_uint] from printf_uint
[67] *((byte*)&printf_buffer) = 0
[68] utoa::value#1 = printf_uint::uvalue#2
[69] call utoa
to:printf_uint::@2
printf_uint::@2: scope:[printf_uint] from printf_uint::@1
[70] printf_number_buffer::buffer_sign#0 = *((byte*)&printf_buffer)
[71] call printf_number_buffer
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint::@2
[72] return
to:@return
void* memset(void* memset::str , byte memset::c , word memset::num)
memset: scope:[memset] from clrscr newline::@4
[73] memset::str#3 = phi( clrscr/memset::str#7, newline::@4/memset::str#8 )
[73] memset::num#2 = phi( clrscr/(word)$28*$18, newline::@4/$28 )
[74] if(memset::num#2<=0) goto memset::@return
to:memset::@1
memset::@1: scope:[memset] from memset
[75] memset::end#0 = (byte*)memset::str#3 + memset::num#2
[76] memset::dst#4 = (byte*)memset::str#3
to:memset::@2
memset::@2: scope:[memset] from memset::@1 memset::@3
[77] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 )
[78] if(memset::dst#2!=memset::end#0) goto memset::@3
to:memset::@return
memset::@return: scope:[memset] from memset memset::@2
[79] return
to:@return
memset::@3: scope:[memset] from memset::@2
[80] *memset::dst#2 = 0
[81] memset::dst#1 = ++ memset::dst#2
to:memset::@2
void gotoxy(byte gotoxy::x , byte gotoxy::y)
gotoxy: scope:[gotoxy] from clrscr::@1
[82] *COLCRS = gotoxy::x#1
[83] *ROWCRS = gotoxy::y#1
[84] call setcursor
to:gotoxy::@return
gotoxy::@return: scope:[gotoxy] from gotoxy
[85] return
to:@return
void cputc(volatile byte cputc::c)
cputc: scope:[cputc] from cputs::@2 printf_number_buffer::@3
[86] if(cputc::c==' 'at) goto cputc::@1
to:cputc::@3
cputc::@3: scope:[cputc] from cputc
[87] if(cputc::c=='
'at) goto cputc::@2
to:cputc::@8
cputc::@8: scope:[cputc] from cputc::@3
[88] if(cputc::c==$9b) goto cputc::@2
to:cputc::convertToScreenCode1
cputc::convertToScreenCode1: scope:[cputc] from cputc::@8
[89] cputc::convertToScreenCode1_return#0 = rawmap[*cputc::convertToScreenCode1_v#0]
to:cputc::@6
cputc::@6: scope:[cputc] from cputc::convertToScreenCode1
[90] phi()
[91] call putchar
to:cputc::@7
cputc::@7: scope:[cputc] from cputc::@6
[92] *COLCRS = ++ *COLCRS
[93] if(*COLCRS==$28) goto cputc::@5
to:cputc::@4
cputc::@4: scope:[cputc] from cputc::@7
[94] phi()
[95] call setcursor
to:cputc::@return
cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@4 cputc::@5
[96] return
to:@return
cputc::@5: scope:[cputc] from cputc::@7
[97] *COLCRS = 0
[98] call newline
to:cputc::@return
cputc::@2: scope:[cputc] from cputc::@3 cputc::@8
[99] *COLCRS = 0
[100] call newline
to:cputc::@return
cputc::@1: scope:[cputc] from cputc
[101] *COLCRS = 0
[102] call setcursor
to:cputc::@return
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
utoa: scope:[utoa] from printf_uint::@1
[103] phi()
to:utoa::@1
utoa::@1: scope:[utoa] from utoa utoa::@4
[104] utoa::buffer#11 = phi( utoa::@4/utoa::buffer#14, utoa/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[104] utoa::started#2 = phi( utoa::@4/utoa::started#4, utoa/0 )
[104] utoa::value#2 = phi( utoa::@4/utoa::value#6, utoa/utoa::value#1 )
[104] utoa::digit#2 = phi( utoa::@4/utoa::digit#1, utoa/0 )
[105] if(utoa::digit#2<5-1) goto utoa::@2
to:utoa::@3
utoa::@3: scope:[utoa] from utoa::@1
[106] utoa::$11 = (byte)utoa::value#2
[107] *utoa::buffer#11 = DIGITS[utoa::$11]
[108] utoa::buffer#3 = ++ utoa::buffer#11
[109] *utoa::buffer#3 = 0
to:utoa::@return
utoa::@return: scope:[utoa] from utoa::@3
[110] return
to:@return
utoa::@2: scope:[utoa] from utoa::@1
[111] utoa::$10 = utoa::digit#2 << 1
[112] utoa::digit_value#0 = RADIX_DECIMAL_VALUES[utoa::$10]
[113] if(0!=utoa::started#2) goto utoa::@5
to:utoa::@7
utoa::@7: scope:[utoa] from utoa::@2
[114] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5
to:utoa::@4
utoa::@4: scope:[utoa] from utoa::@6 utoa::@7
[115] utoa::buffer#14 = phi( utoa::@7/utoa::buffer#11, utoa::@6/utoa::buffer#4 )
[115] utoa::started#4 = phi( utoa::@7/utoa::started#2, utoa::@6/1 )
[115] utoa::value#6 = phi( utoa::@7/utoa::value#2, utoa::@6/utoa::value#0 )
[116] utoa::digit#1 = ++ utoa::digit#2
to:utoa::@1
utoa::@5: scope:[utoa] from utoa::@2 utoa::@7
[117] utoa_append::buffer#0 = utoa::buffer#11
[118] utoa_append::value#0 = utoa::value#2
[119] utoa_append::sub#0 = utoa::digit_value#0
[120] call utoa_append
[121] utoa_append::return#0 = utoa_append::value#2
to:utoa::@6
utoa::@6: scope:[utoa] from utoa::@5
[122] utoa::value#0 = utoa_append::return#0
[123] utoa::buffer#4 = ++ utoa::buffer#11
to:utoa::@4
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
printf_number_buffer: scope:[printf_number_buffer] from printf_uint::@2
[124] phi()
to:printf_number_buffer::@1
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer
[125] if(0==printf_number_buffer::buffer_sign#0) goto printf_number_buffer::@2
to:printf_number_buffer::@3
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@1
[126] cputc::c = printf_number_buffer::buffer_sign#0
[127] call cputc
to:printf_number_buffer::@2
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@3
[128] phi()
[129] call cputs
to:printf_number_buffer::@return
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@2
[130] return
to:@return
void setcursor()
setcursor: scope:[setcursor] from cputc::@1 cputc::@4 gotoxy newline::@1 putchar::@1
[131] *(*OLDADR) = *OLDCHR
[132] call cursorLocation
[133] cursorLocation::return#3 = cursorLocation::return#1
to:setcursor::@3
setcursor::@3: scope:[setcursor] from setcursor
[134] setcursor::loc#0 = cursorLocation::return#3
[135] setcursor::c#0 = *setcursor::loc#0
[136] *OLDCHR = setcursor::c#0
[137] *OLDADR = setcursor::loc#0
to:setcursor::@2
setcursor::@2: scope:[setcursor] from setcursor::@3
[138] *CRSINH = 0
[139] setcursor::c#1 = setcursor::c#0 ^ $80
to:setcursor::@1
setcursor::@1: scope:[setcursor] from setcursor::@2
[140] *(*OLDADR) = setcursor::c#1
to:setcursor::@return
setcursor::@return: scope:[setcursor] from setcursor::@1
[141] return
to:@return
void putchar(byte putchar::code)
putchar: scope:[putchar] from cputc::@6
[142] *(*OLDADR) = *OLDCHR
[143] call cursorLocation
[144] cursorLocation::return#0 = cursorLocation::return#1
to:putchar::@1
putchar::@1: scope:[putchar] from putchar
[145] putchar::loc#0 = cursorLocation::return#0
[146] putchar::newChar#0 = cputc::convertToScreenCode1_return#0
[147] *putchar::loc#0 = putchar::newChar#0
[148] *OLDCHR = putchar::newChar#0
[149] call setcursor
to:putchar::@return
putchar::@return: scope:[putchar] from putchar::@1
[150] return
to:@return
void newline()
newline: scope:[newline] from cputc::@2 cputc::@5
[151] *ROWCRS = ++ *ROWCRS
[152] if(*ROWCRS!=$18) goto newline::@1
to:newline::@3
newline::@3: scope:[newline] from newline
[153] *(*OLDADR) = *(*OLDADR) ^ $80
to:newline::@2
newline::@2: scope:[newline] from newline::@3
[154] newline::start#0 = *SAVMSC
[155] memcpy::source#0 = newline::start#0 + $28
[156] memcpy::destination#0 = (void*)newline::start#0
[157] call memcpy
to:newline::@4
newline::@4: scope:[newline] from newline::@2
[158] memset::str#0 = newline::start#0 + (word)$28*$17
[159] memset::str#8 = (void*)memset::str#0
[160] call memset
to:newline::@5
newline::@5: scope:[newline] from newline::@4
[161] *ROWCRS = (byte)$18-1
to:newline::@1
newline::@1: scope:[newline] from newline newline::@5
[162] phi()
[163] call setcursor
to:newline::@return
newline::@return: scope:[newline] from newline::@1
[164] return
to:@return
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
utoa_append: scope:[utoa_append] from utoa::@5
[165] phi()
to:utoa_append::@1
utoa_append::@1: scope:[utoa_append] from utoa_append utoa_append::@2
[166] utoa_append::digit#2 = phi( utoa_append/0, utoa_append::@2/utoa_append::digit#1 )
[166] utoa_append::value#2 = phi( utoa_append/utoa_append::value#0, utoa_append::@2/utoa_append::value#1 )
[167] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2
to:utoa_append::@3
utoa_append::@3: scope:[utoa_append] from utoa_append::@1
[168] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2]
to:utoa_append::@return
utoa_append::@return: scope:[utoa_append] from utoa_append::@3
[169] return
to:@return
utoa_append::@2: scope:[utoa_append] from utoa_append::@1
[170] utoa_append::digit#1 = ++ utoa_append::digit#2
[171] utoa_append::value#1 = utoa_append::value#2 - utoa_append::sub#0
to:utoa_append::@1
byte* cursorLocation()
cursorLocation: scope:[cursorLocation] from putchar setcursor
[172] cursorLocation::$3 = (word)*ROWCRS
[173] cursorLocation::$4 = cursorLocation::$3 << 2
[174] cursorLocation::$5 = cursorLocation::$4 + cursorLocation::$3
[175] cursorLocation::$0 = cursorLocation::$5 << 3
[176] cursorLocation::$1 = *SAVMSC + cursorLocation::$0
[177] cursorLocation::return#1 = cursorLocation::$1 + *COLCRS
to:cursorLocation::@return
cursorLocation::@return: scope:[cursorLocation] from cursorLocation
[178] return
to:@return
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
memcpy: scope:[memcpy] from newline::@2
[179] memcpy::src_end#0 = (byte*)(void*)memcpy::source#0 + memcpy::num#0
[180] memcpy::src#4 = (byte*)(void*)memcpy::source#0
[181] memcpy::dst#4 = (byte*)memcpy::destination#0
to:memcpy::@1
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
[182] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
[182] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
[183] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
to:memcpy::@return
memcpy::@return: scope:[memcpy] from memcpy::@1
[184] return
to:@return
memcpy::@2: scope:[memcpy] from memcpy::@1
[185] *memcpy::dst#2 = *memcpy::src#2
[186] memcpy::dst#1 = ++ memcpy::dst#2
[187] memcpy::src#1 = ++ memcpy::src#2
to:memcpy::@1

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -183,8 +183,8 @@ MakeNiceScreen::@2: scope:[MakeNiceScreen] from MakeNiceScreen::@1
to:MakeNiceScreen::@17
MakeNiceScreen::@17: scope:[MakeNiceScreen] from MakeNiceScreen::@2
[89] MakeNiceScreen::$22 = strlen::return#2
[90] MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22
[91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34
[90] MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22
[91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30
[92] MakeNiceScreen::X#1 = MakeNiceScreen::$23 >> 1
[93] cputsxy::s#0 = (byte*)MakeNiceScreen::T#3 + 1
[94] cputsxy::x#0 = MakeNiceScreen::X#1

View File

@ -726,9 +726,9 @@ MakeNiceScreen::@1: scope:[MakeNiceScreen] from MakeNiceScreen::@18 MakeNiceScr
MakeNiceScreen::@2: scope:[MakeNiceScreen] from MakeNiceScreen::@1
MakeNiceScreen::I#6 = phi( MakeNiceScreen::@1/MakeNiceScreen::I#3 )
MakeNiceScreen::T#3 = phi( MakeNiceScreen::@1/MakeNiceScreen::T#6 )
MakeNiceScreen::$33 = (byte*)MakeNiceScreen::T#3
MakeNiceScreen::$29 = MakeNiceScreen::$33 + OFFSET_STRUCT_$0_MSG
strlen::str#1 = MakeNiceScreen::$29
MakeNiceScreen::$29 = (byte*)MakeNiceScreen::T#3
MakeNiceScreen::$26 = MakeNiceScreen::$29 + OFFSET_STRUCT_$0_MSG
strlen::str#1 = MakeNiceScreen::$26
call strlen
strlen::return#2 = strlen::return#1
to:MakeNiceScreen::@19
@ -737,17 +737,17 @@ MakeNiceScreen::@19: scope:[MakeNiceScreen] from MakeNiceScreen::@2
MakeNiceScreen::T#4 = phi( MakeNiceScreen::@2/MakeNiceScreen::T#3 )
strlen::return#4 = phi( MakeNiceScreen::@2/strlen::return#2 )
MakeNiceScreen::$22 = strlen::return#4
MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22
MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34
MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22
MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30
MakeNiceScreen::$24 = MakeNiceScreen::$23 >> 1
MakeNiceScreen::X#1 = MakeNiceScreen::$24
MakeNiceScreen::$37 = (byte*)MakeNiceScreen::T#4
MakeNiceScreen::$30 = MakeNiceScreen::$37 + OFFSET_STRUCT_$0_Y
MakeNiceScreen::$38 = (byte*)MakeNiceScreen::T#4
MakeNiceScreen::$31 = MakeNiceScreen::$38 + OFFSET_STRUCT_$0_MSG
MakeNiceScreen::$31 = (byte*)MakeNiceScreen::T#4
MakeNiceScreen::$27 = MakeNiceScreen::$31 + OFFSET_STRUCT_$0_Y
MakeNiceScreen::$32 = (byte*)MakeNiceScreen::T#4
MakeNiceScreen::$28 = MakeNiceScreen::$32 + OFFSET_STRUCT_$0_MSG
cputsxy::x#0 = MakeNiceScreen::X#1
cputsxy::y#0 = *MakeNiceScreen::$30
cputsxy::s#0 = MakeNiceScreen::$31
cputsxy::y#0 = *MakeNiceScreen::$27
cputsxy::s#0 = MakeNiceScreen::$28
call cputsxy
to:MakeNiceScreen::@20
MakeNiceScreen::@20: scope:[MakeNiceScreen] from MakeNiceScreen::@19
@ -812,13 +812,13 @@ bool~ MakeNiceScreen::$21
word~ MakeNiceScreen::$22
byte~ MakeNiceScreen::$23
byte~ MakeNiceScreen::$24
byte*~ MakeNiceScreen::$26
byte*~ MakeNiceScreen::$27
byte*~ MakeNiceScreen::$28
byte*~ MakeNiceScreen::$29
byte*~ MakeNiceScreen::$30
byte~ MakeNiceScreen::$30
byte*~ MakeNiceScreen::$31
byte*~ MakeNiceScreen::$33
byte~ MakeNiceScreen::$34
byte*~ MakeNiceScreen::$37
byte*~ MakeNiceScreen::$38
byte*~ MakeNiceScreen::$32
number~ MakeNiceScreen::$7
byte MakeNiceScreen::I
byte MakeNiceScreen::I#0
@ -1519,10 +1519,10 @@ Alias chline::length#2 = MakeNiceScreen::$12
Alias cvlinexy::x#1 = MakeNiceScreen::$15
Alias MakeNiceScreen::T#3 = MakeNiceScreen::T#6 MakeNiceScreen::T#4 MakeNiceScreen::T#5
Alias MakeNiceScreen::I#3 = MakeNiceScreen::I#6 MakeNiceScreen::I#5 MakeNiceScreen::I#4
Alias strlen::str#1 = MakeNiceScreen::$29
Alias strlen::str#1 = MakeNiceScreen::$26
Alias strlen::return#2 = strlen::return#4
Alias MakeNiceScreen::X#1 = MakeNiceScreen::$24
Alias cputsxy::s#0 = MakeNiceScreen::$31
Alias cputsxy::s#0 = MakeNiceScreen::$28
Successful SSA optimization Pass2AliasElimination
Alias candidate removed (volatile)conio_line_text = gotoxy::$5
Alias candidate removed (volatile)conio_line_color = gotoxy::$6
@ -1641,10 +1641,10 @@ Constant MakeNiceScreen::T#1 = MakeNiceScreen::Text
Constant MakeNiceScreen::$19 = sizeof MakeNiceScreen::Text
Successful SSA optimization Pass2ConstantIdentification
Rewriting conditional comparison [56] if(gotoxy::y#7<=$19) goto gotoxy::@1
Converting *(pointer+n) to pointer[n] [298] cputsxy::y#0 = *MakeNiceScreen::$30 -- MakeNiceScreen::$37[OFFSET_STRUCT_$0_Y]
Converting *(pointer+n) to pointer[n] [298] cputsxy::y#0 = *MakeNiceScreen::$27 -- MakeNiceScreen::$31[OFFSET_STRUCT_$0_Y]
Successful SSA optimization Pass2InlineDerefIdx
Simplifying expression containing zero MakeNiceScreen::$37 in [294] MakeNiceScreen::$30 = MakeNiceScreen::$37 + OFFSET_STRUCT_$0_Y
Simplifying expression containing zero MakeNiceScreen::$37 in [298] cputsxy::y#0 = MakeNiceScreen::$37[OFFSET_STRUCT_$0_Y]
Simplifying expression containing zero MakeNiceScreen::$31 in [294] MakeNiceScreen::$27 = MakeNiceScreen::$31 + OFFSET_STRUCT_$0_Y
Simplifying expression containing zero MakeNiceScreen::$31 in [298] cputsxy::y#0 = MakeNiceScreen::$31[OFFSET_STRUCT_$0_Y]
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable memcpy::return#2 and assignment [76] memcpy::return#2 = memcpy::destination#2
Eliminating unused variable memcpy::return#3 and assignment [78] memcpy::return#3 = memcpy::destination#2
@ -1655,7 +1655,7 @@ Eliminating unused variable textcolor::return#2 and assignment [176] textcolor::
Eliminating unused variable bordercolor::return#2 and assignment [178] bordercolor::return#2 = bordercolor::return#0
Eliminating unused variable bgcolor::return#2 and assignment [180] bgcolor::return#2 = bgcolor::return#0
Eliminating unused variable cursor::return#2 and assignment [183] cursor::return#2 = cursor::return#0
Eliminating unused variable MakeNiceScreen::$30 and assignment [209] MakeNiceScreen::$30 = MakeNiceScreen::$37
Eliminating unused variable MakeNiceScreen::$27 and assignment [209] MakeNiceScreen::$27 = MakeNiceScreen::$31
Eliminating unused constant cputs::c#0
Eliminating unused constant MakeNiceScreen::T#0
Eliminating unused constant MakeNiceScreen::I#0
@ -1709,9 +1709,9 @@ Inlining Noop Cast [2] memcpy::dst#0 = (byte*)memcpy::destination#2 keeping memc
Inlining Noop Cast [3] memcpy::$2 = (byte*)memcpy::source#2 keeping memcpy::source#2
Inlining Noop Cast [13] memset::$4 = (byte*)memset::str#3 keeping memset::str#3
Inlining Noop Cast [15] memset::dst#0 = (byte*)memset::str#3 keeping memset::str#3
Inlining Noop Cast [182] MakeNiceScreen::$33 = (byte*)MakeNiceScreen::T#3 keeping MakeNiceScreen::T#3
Inlining Noop Cast [190] MakeNiceScreen::$37 = (byte*)MakeNiceScreen::T#3 keeping MakeNiceScreen::T#3
Inlining Noop Cast [191] MakeNiceScreen::$38 = (byte*)MakeNiceScreen::T#3 keeping MakeNiceScreen::T#3
Inlining Noop Cast [182] MakeNiceScreen::$29 = (byte*)MakeNiceScreen::T#3 keeping MakeNiceScreen::T#3
Inlining Noop Cast [190] MakeNiceScreen::$31 = (byte*)MakeNiceScreen::T#3 keeping MakeNiceScreen::T#3
Inlining Noop Cast [191] MakeNiceScreen::$32 = (byte*)MakeNiceScreen::T#3 keeping MakeNiceScreen::T#3
Successful SSA optimization Pass2NopCastInlining
Rewriting multiplication to use shift and addition[49] gotoxy::line_offset#0 = gotoxy::$7 * $28
Inlining constant with var siblings memcpy::destination#0
@ -2213,8 +2213,8 @@ MakeNiceScreen::@2: scope:[MakeNiceScreen] from MakeNiceScreen::@1
to:MakeNiceScreen::@17
MakeNiceScreen::@17: scope:[MakeNiceScreen] from MakeNiceScreen::@2
[89] MakeNiceScreen::$22 = strlen::return#2
[90] MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22
[91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34
[90] MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22
[91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30
[92] MakeNiceScreen::X#1 = MakeNiceScreen::$23 >> 1
[93] cputsxy::s#0 = (byte*)MakeNiceScreen::T#3 + 1
[94] cputsxy::x#0 = MakeNiceScreen::X#1
@ -2579,7 +2579,7 @@ VARIABLE REGISTER WEIGHTS
void MakeNiceScreen()
word~ MakeNiceScreen::$22 1001.0
byte~ MakeNiceScreen::$23 2002.0
byte~ MakeNiceScreen::$34 2002.0
byte~ MakeNiceScreen::$30 2002.0
byte MakeNiceScreen::I
byte MakeNiceScreen::I#2 2002.0
byte MakeNiceScreen::I#3 214.5
@ -2806,7 +2806,7 @@ Added variable gotoxy::$5 to live range equivalence class [ gotoxy::$5 ]
Added variable gotoxy::$6 to live range equivalence class [ gotoxy::$6 ]
Added variable strlen::return#2 to live range equivalence class [ strlen::return#2 ]
Added variable MakeNiceScreen::$22 to live range equivalence class [ MakeNiceScreen::$22 ]
Added variable MakeNiceScreen::$34 to live range equivalence class [ MakeNiceScreen::$34 ]
Added variable MakeNiceScreen::$30 to live range equivalence class [ MakeNiceScreen::$30 ]
Added variable MakeNiceScreen::$23 to live range equivalence class [ MakeNiceScreen::$23 ]
Added variable MakeNiceScreen::X#1 to live range equivalence class [ MakeNiceScreen::X#1 ]
Added variable cputsxy::s#0 to live range equivalence class [ cputsxy::s#0 ]
@ -2864,7 +2864,7 @@ Complete equivalence classes
[ gotoxy::$6 ]
[ strlen::return#2 ]
[ MakeNiceScreen::$22 ]
[ MakeNiceScreen::$34 ]
[ MakeNiceScreen::$30 ]
[ MakeNiceScreen::$23 ]
[ MakeNiceScreen::X#1 ]
[ cputsxy::s#0 ]
@ -2921,7 +2921,7 @@ Allocated zp[2]:62 [ gotoxy::$5 ]
Allocated zp[2]:64 [ gotoxy::$6 ]
Allocated zp[2]:66 [ strlen::return#2 ]
Allocated zp[2]:68 [ MakeNiceScreen::$22 ]
Allocated zp[1]:70 [ MakeNiceScreen::$34 ]
Allocated zp[1]:70 [ MakeNiceScreen::$30 ]
Allocated zp[1]:71 [ MakeNiceScreen::$23 ]
Allocated zp[1]:72 [ MakeNiceScreen::X#1 ]
Allocated zp[2]:73 [ cputsxy::s#0 ]
@ -2962,8 +2962,8 @@ Statement [51] *screensize::y#0 = $19 [ ] ( main:11::screensize:21 [ XSize ] { }
Statement [86] strlen::str#1 = (byte*)MakeNiceScreen::T#3 + 1 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::str#1 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::str#1 ] { { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a
Statement [88] strlen::return#2 = strlen::len#2 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::return#2 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::return#2 ] { { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a
Statement [89] MakeNiceScreen::$22 = strlen::return#2 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$22 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$22 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [90] MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$34 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$34 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [90] MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$30 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$30 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [92] MakeNiceScreen::X#1 = MakeNiceScreen::$23 >> 1 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [93] cputsxy::s#0 = (byte*)MakeNiceScreen::T#3 + 1 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 cputsxy::s#0 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 cputsxy::s#0 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:72 [ MakeNiceScreen::X#1 ]
@ -3039,8 +3039,8 @@ Statement [51] *screensize::y#0 = $19 [ ] ( main:11::screensize:21 [ XSize ] { }
Statement [86] strlen::str#1 = (byte*)MakeNiceScreen::T#3 + 1 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::str#1 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::str#1 ] { { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a
Statement [88] strlen::return#2 = strlen::len#2 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::return#2 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 strlen::return#2 ] { { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a
Statement [89] MakeNiceScreen::$22 = strlen::return#2 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$22 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$22 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [90] MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$34 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$34 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [90] MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$30 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$30 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::$23 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [92] MakeNiceScreen::X#1 = MakeNiceScreen::$23 >> 1 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [93] cputsxy::s#0 = (byte*)MakeNiceScreen::T#3 + 1 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 cputsxy::s#0 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 MakeNiceScreen::X#1 cputsxy::s#0 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a
Statement [95] cputsxy::y#0 = *((byte*)MakeNiceScreen::T#3) [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 cputsxy::s#0 cputsxy::x#0 cputsxy::y#0 ] ( main:11::MakeNiceScreen:23 [ conio_textcolor conio_scroll_enable XSize MakeNiceScreen::I#3 MakeNiceScreen::T#3 cputsxy::s#0 cputsxy::x#0 cputsxy::y#0 ] { { cputsxy::x#0 = MakeNiceScreen::X#1 } } ) always clobbers reg byte a reg byte y
@ -3127,7 +3127,7 @@ Potential registers zp[2]:62 [ gotoxy::$5 ] : zp[2]:62 ,
Potential registers zp[2]:64 [ gotoxy::$6 ] : zp[2]:64 ,
Potential registers zp[2]:66 [ strlen::return#2 ] : zp[2]:66 ,
Potential registers zp[2]:68 [ MakeNiceScreen::$22 ] : zp[2]:68 ,
Potential registers zp[1]:70 [ MakeNiceScreen::$34 ] : zp[1]:70 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:70 [ MakeNiceScreen::$30 ] : zp[1]:70 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:71 [ MakeNiceScreen::$23 ] : zp[1]:71 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:72 [ MakeNiceScreen::X#1 ] : zp[1]:72 , reg byte x , reg byte y ,
Potential registers zp[2]:73 [ cputsxy::s#0 ] : zp[2]:73 ,
@ -3152,7 +3152,7 @@ Uplift Scope [cvline] 237,502.38: zp[1]:25 [ cvline::i#2 cvline::i#1 ] 132,503.3
Uplift Scope [chline] 275,002.75: zp[1]:17 [ chline::i#2 chline::i#1 ] 19,273.33: zp[1]:16 [ chline::length#4 chline::length#2 chline::length#1 chline::length#0 ]
Uplift Scope [cputcxy] 13,004: zp[1]:14 [ cputcxy::y#2 cputcxy::y#0 ] 3,333.67: zp[1]:15 [ cputcxy::c#2 ]
Uplift Scope [cputsxy] 5,501: zp[1]:75 [ cputsxy::x#0 ] 5,501: zp[1]:76 [ cputsxy::y#0 ] 1,833.67: zp[2]:73 [ cputsxy::s#0 ]
Uplift Scope [MakeNiceScreen] 2,216.5: zp[1]:5 [ MakeNiceScreen::I#3 MakeNiceScreen::I#2 ] 2,002: zp[1]:70 [ MakeNiceScreen::$34 ] 2,002: zp[1]:71 [ MakeNiceScreen::$23 ] 1,155: zp[2]:6 [ MakeNiceScreen::T#3 MakeNiceScreen::T#2 ] 1,001: zp[2]:68 [ MakeNiceScreen::$22 ] 1,001: zp[1]:72 [ MakeNiceScreen::X#1 ]
Uplift Scope [MakeNiceScreen] 2,216.5: zp[1]:5 [ MakeNiceScreen::I#3 MakeNiceScreen::I#2 ] 2,002: zp[1]:70 [ MakeNiceScreen::$30 ] 2,002: zp[1]:71 [ MakeNiceScreen::$23 ] 1,155: zp[2]:6 [ MakeNiceScreen::T#3 MakeNiceScreen::T#2 ] 1,001: zp[2]:68 [ MakeNiceScreen::$22 ] 1,001: zp[1]:72 [ MakeNiceScreen::X#1 ]
Uplift Scope [cvlinexy] 1,304: zp[1]:19 [ cvlinexy::x#2 cvlinexy::x#1 ]
Uplift Scope [MakeTeeLine] 1,001: zp[1]:20 [ MakeTeeLine::Y#2 ]
Uplift Scope [kbhit] 367.33: zp[1]:77 [ kbhit::return#0 ] 202: zp[1]:52 [ kbhit::return#2 ]
@ -3183,7 +3183,7 @@ Uplifting [cvline] best 131919 combination zp[1]:25 [ cvline::i#2 cvline::i#1 ]
Uplifting [chline] best 131919 combination zp[1]:17 [ chline::i#2 chline::i#1 ] zp[1]:16 [ chline::length#4 chline::length#2 chline::length#1 chline::length#0 ]
Uplifting [cputcxy] best 131903 combination reg byte a [ cputcxy::y#2 cputcxy::y#0 ] reg byte y [ cputcxy::c#2 ]
Uplifting [cputsxy] best 131837 combination reg byte x [ cputsxy::x#0 ] reg byte a [ cputsxy::y#0 ] zp[2]:73 [ cputsxy::s#0 ]
Uplifting [MakeNiceScreen] best 131697 combination zp[1]:5 [ MakeNiceScreen::I#3 MakeNiceScreen::I#2 ] reg byte a [ MakeNiceScreen::$34 ] reg byte a [ MakeNiceScreen::$23 ] zp[2]:6 [ MakeNiceScreen::T#3 MakeNiceScreen::T#2 ] zp[2]:68 [ MakeNiceScreen::$22 ] reg byte x [ MakeNiceScreen::X#1 ]
Uplifting [MakeNiceScreen] best 131697 combination zp[1]:5 [ MakeNiceScreen::I#3 MakeNiceScreen::I#2 ] reg byte a [ MakeNiceScreen::$30 ] reg byte a [ MakeNiceScreen::$23 ] zp[2]:6 [ MakeNiceScreen::T#3 MakeNiceScreen::T#2 ] zp[2]:68 [ MakeNiceScreen::$22 ] reg byte x [ MakeNiceScreen::X#1 ]
Uplifting [cvlinexy] best 131688 combination reg byte x [ cvlinexy::x#2 cvlinexy::x#1 ]
Uplifting [MakeTeeLine] best 131679 combination reg byte a [ MakeTeeLine::Y#2 ]
Uplifting [kbhit] best 131586 combination reg byte a [ kbhit::return#0 ] reg byte a [ kbhit::return#2 ]
@ -3779,9 +3779,9 @@ MakeNiceScreen: {
// MakeNiceScreen::@17
__b17:
// [89] MakeNiceScreen::$22 = strlen::return#2
// [90] MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22 -- vbuaa=_byte_vwuz1
// [90] MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22 -- vbuaa=_byte_vwuz1
lda.z __22
// [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34 -- vbuaa=vbuz1_minus_vbuaa
// [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30 -- vbuaa=vbuz1_minus_vbuaa
eor #$ff
sec
adc.z XSize
@ -4963,7 +4963,7 @@ const nomodify byte LIGHT_BLUE = $e
void MakeNiceScreen()
word~ MakeNiceScreen::$22 zp[2]:5 1001.0
byte~ MakeNiceScreen::$23 reg byte a 2002.0
byte~ MakeNiceScreen::$34 reg byte a 2002.0
byte~ MakeNiceScreen::$30 reg byte a 2002.0
byte MakeNiceScreen::I
byte MakeNiceScreen::I#2 I zp[1]:2 2002.0
byte MakeNiceScreen::I#3 I zp[1]:2 214.5
@ -5185,7 +5185,7 @@ reg byte a [ main::$3 ]
zp[2]:23 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ]
zp[2]:25 [ gotoxy::$8 ]
zp[2]:27 [ gotoxy::$5 ]
reg byte a [ MakeNiceScreen::$34 ]
reg byte a [ MakeNiceScreen::$30 ]
reg byte a [ MakeNiceScreen::$23 ]
reg byte x [ MakeNiceScreen::X#1 ]
reg byte x [ cputsxy::x#0 ]
@ -5660,9 +5660,9 @@ MakeNiceScreen: {
// MakeNiceScreen::@17
// [89] MakeNiceScreen::$22 = strlen::return#2
// XSize - (char)strlen (T->Msg)
// [90] MakeNiceScreen::$34 = (byte)MakeNiceScreen::$22 -- vbuaa=_byte_vwuz1
// [90] MakeNiceScreen::$30 = (byte)MakeNiceScreen::$22 -- vbuaa=_byte_vwuz1
lda.z __22
// [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$34 -- vbuaa=vbuz1_minus_vbuaa
// [91] MakeNiceScreen::$23 = XSize - MakeNiceScreen::$30 -- vbuaa=vbuz1_minus_vbuaa
eor #$ff
sec
adc.z XSize

View File

@ -14,7 +14,7 @@ const nomodify byte LIGHT_BLUE = $e
void MakeNiceScreen()
word~ MakeNiceScreen::$22 zp[2]:5 1001.0
byte~ MakeNiceScreen::$23 reg byte a 2002.0
byte~ MakeNiceScreen::$34 reg byte a 2002.0
byte~ MakeNiceScreen::$30 reg byte a 2002.0
byte MakeNiceScreen::I
byte MakeNiceScreen::I#2 I zp[1]:2 2002.0
byte MakeNiceScreen::I#3 I zp[1]:2 214.5
@ -236,7 +236,7 @@ reg byte a [ main::$3 ]
zp[2]:23 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ]
zp[2]:25 [ gotoxy::$8 ]
zp[2]:27 [ gotoxy::$5 ]
reg byte a [ MakeNiceScreen::$34 ]
reg byte a [ MakeNiceScreen::$30 ]
reg byte a [ MakeNiceScreen::$23 ]
reg byte x [ MakeNiceScreen::X#1 ]
reg byte x [ cputsxy::x#0 ]

View File

@ -2,6 +2,7 @@ Fixing struct type size struct printf_buffer_number to 12
Fixing struct type size struct printf_buffer_number to 12
Fixing struct type SIZE_OF struct printf_buffer_number to 12
Fixing struct type SIZE_OF struct printf_buffer_number to 12
Converting variable modified inside __stackcall procedure queen() to load/store count
Added struct type cast to parameter value list call printf_uint 8 (struct printf_format_number){ 0, 0, 0, 0, 0, DECIMAL }
Added struct type cast to parameter value list call printf_ulong count (struct printf_format_number){ 0, 0, 0, 0, 0, DECIMAL }
Added struct type cast to parameter value list call printf_string main::$6 (struct printf_format_string){ 0, 0 }
@ -21,9 +22,8 @@ Eliminating unused variable with no statement print::$3
Eliminating unused variable with no statement print::$5
Eliminating unused variable with no statement print::$8
Eliminating unused variable with no statement print::$9
Converting PHI-variable modified inside __stackcall procedure queen() to load/store count
Calling convention STACK_CALL adding prepare/execute/finalize for call queen 1
Calling convention STACK_CALL adding prepare/execute/finalize for call queen queen::$4
Calling convention __stackcall adding prepare/execute/finalize for call queen 1
Calling convention __stackcall adding prepare/execute/finalize for call queen queen::$4
Calling convention STACK_CALL replacing param(queen::row) with stackidx(byte,queen::OFFSET_STACK_ROW)
Calling convention STACK_CALL adding stack push stackpush(byte) = 1
Calling convention STACK_CALL adding stack push stackpush(byte) = queen::$4

View File

@ -85,10 +85,9 @@ main: {
iny
lda (__3),y
adc (__9),y
sta (__3),y
dey
sta.z __3+1
pla
sta (__3),y
sta.z __3
// fibs[i+2] = fibs[i]+fibs[i+1]
asl.z __8
rol.z __8+1

View File

@ -360,10 +360,9 @@ main: {
iny
lda (__3),y
adc (__9),y
sta (__3),y
dey
sta.z __3+1
pla
sta (__3),y
sta.z __3
// [12] main::$8 = main::$1 << 1 -- vwuz1=vwuz1_rol_1
asl.z __8
rol.z __8+1
@ -432,7 +431,7 @@ zp[2]:8 [ main::$6 main::$9 ]
FINAL ASSEMBLER
Score: 2361
Score: 2281
// File Comments
// Test array index pointer rewriting
@ -541,10 +540,9 @@ main: {
iny
lda (__3),y
adc (__9),y
sta (__3),y
dey
sta.z __3+1
pla
sta (__3),y
sta.z __3
// fibs[i+2] = fibs[i]+fibs[i+1]
// [12] main::$8 = main::$1 << 1 -- vwuz1=vwuz1_rol_1
asl.z __8

View File

@ -1,5 +1,5 @@
// Tests the target platform ASM6502
.pc = $2000 "Program"
.pc = $3000 "Program"
main: {
ldx #0
__b1:

View File

@ -112,7 +112,7 @@ ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Tests the target platform ASM6502
// Upstart
.pc = $2000 "Program"
.pc = $3000 "Program"
// Global Constants & labels
// main
main: {
@ -171,7 +171,7 @@ Score: 191
// File Comments
// Tests the target platform ASM6502
// Upstart
.pc = $2000 "Program"
.pc = $3000 "Program"
// Global Constants & labels
// main
main: {

View File

@ -1,4 +1,4 @@
Calling convention STACK_CALL adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return

View File

@ -1,4 +1,4 @@
Calling convention STACK_CALL adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return

View File

@ -1,9 +1,9 @@
Converting variable modified inside __stackcall procedure main() to load/store idx
Inlined call call __init
Eliminating unused variable with no statement main::$1
Converting PHI-variable modified inside __stackcall procedure main() to load/store idx
Calling convention STACK_CALL adding prepare/execute/finalize for { main::$1_x, main::$1_y } = call get main::i
Calling convention STACK_CALL adding prepare/execute/finalize for call print main::p_x main::p_y
Calling convention STACK_CALL adding prepare/execute/finalize for call main
Calling convention __stackcall adding prepare/execute/finalize for { main::$1_x, main::$1_y } = call get main::i
Calling convention __stackcall adding prepare/execute/finalize for call print main::p_x main::p_y
Calling convention __stackcall adding prepare/execute/finalize for call main
Calling convention STACK_CALL replacing param(get::i) with stackidx(byte,get::OFFSET_STACK_I)
Calling convention STACK_CALL replacing param(print::p_x) with stackidx(byte,print::OFFSET_STACK_P_X)
Calling convention STACK_CALL replacing param(print::p_y) with stackidx(byte,print::OFFSET_STACK_P_Y)

View File

@ -1,11 +1,11 @@
Converting variable modified inside __stackcall procedure main() to load/store idx
Inlined call call __init
Eliminating unused variable with no statement main::$1
Eliminating unused variable with no statement main::$1_p1
Eliminating unused variable with no statement main::$1_p2
Converting PHI-variable modified inside __stackcall procedure main() to load/store idx
Calling convention STACK_CALL adding prepare/execute/finalize for { { main::$1_p1_x, main::$1_p1_y }, { main::$1_p2_x, main::$1_p2_y } } = call get main::i
Calling convention STACK_CALL adding prepare/execute/finalize for call print main::v_p1_x main::v_p1_y main::v_p2_x main::v_p2_y
Calling convention STACK_CALL adding prepare/execute/finalize for call main
Calling convention __stackcall adding prepare/execute/finalize for { { main::$1_p1_x, main::$1_p1_y }, { main::$1_p2_x, main::$1_p2_y } } = call get main::i
Calling convention __stackcall adding prepare/execute/finalize for call print main::v_p1_x main::v_p1_y main::v_p2_x main::v_p2_y
Calling convention __stackcall adding prepare/execute/finalize for call main
Calling convention STACK_CALL replacing param(get::i) with stackidx(byte,get::OFFSET_STACK_I)
Calling convention STACK_CALL replacing param(print::v_p1_x) with stackidx(byte,print::OFFSET_STACK_V_P1_X)
Calling convention STACK_CALL replacing param(print::v_p1_y) with stackidx(byte,print::OFFSET_STACK_V_P1_Y)

View File

@ -1,8 +1,8 @@
Converting variable modified inside __stackcall procedure main() to load/store idx
Inlined call call __init
Converting PHI-variable modified inside __stackcall procedure main() to load/store idx
Calling convention STACK_CALL adding prepare/execute/finalize for call print main::str 1
Calling convention STACK_CALL adding prepare/execute/finalize for call print main::str1 2
Calling convention STACK_CALL adding prepare/execute/finalize for call main
Calling convention __stackcall adding prepare/execute/finalize for call print main::str 1
Calling convention __stackcall adding prepare/execute/finalize for call print main::str1 2
Calling convention __stackcall adding prepare/execute/finalize for call main
Calling convention STACK_CALL replacing param(print::str) with stackidx(byte*,print::OFFSET_STACK_STR)
Calling convention STACK_CALL replacing param(print::spacing) with stackidx(byte,print::OFFSET_STACK_SPACING)
Calling convention STACK_CALL adding stack push stackpush(byte*) = main::str

View File

@ -1,5 +1,5 @@
Calling convention STACK_CALL adding prepare/execute/finalize for main::$0 = call pow2 6
Calling convention STACK_CALL adding prepare/execute/finalize for pow2::$2 = call pow2 pow2::$1
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call pow2 6
Calling convention __stackcall adding prepare/execute/finalize for pow2::$2 = call pow2 pow2::$1
Calling convention STACK_CALL replacing param(pow2::n) with stackidx(byte,pow2::OFFSET_STACK_N)
Calling convention STACK_CALL adding stack return stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return
Calling convention STACK_CALL adding stack pull main::$0 = stackpull(byte)

View File

@ -1,4 +1,4 @@
Calling convention STACK_CALL adding prepare/execute/finalize for main::$0 = call plus $1234 $2345
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus $1234 $2345
Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return

View File

@ -1,4 +1,4 @@
Calling convention STACK_CALL adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return

View File

@ -1,6 +1,6 @@
Converting variable modified inside __stackcall procedure plus() to load/store i
Inlined call call __init
Converting PHI-variable modified inside __stackcall procedure plus() to load/store i
Calling convention STACK_CALL adding prepare/execute/finalize for main::$1 = call plus '0' main::v
Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call plus '0' main::v
Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return

View File

@ -1,7 +1,7 @@
Converting variable modified inside __stackcall procedure next() to load/store current
Inlined call call __init
Converting PHI-variable modified inside __stackcall procedure next() to load/store current
Calling convention STACK_CALL adding prepare/execute/finalize for main::$0 = call next
Calling convention STACK_CALL adding prepare/execute/finalize for main::$1 = call next
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call next
Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call next
Calling convention STACK_CALL adding stack return stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return
Calling convention STACK_CALL adding stack pull main::$0 = stackpull(signed word)
Calling convention STACK_CALL adding stack pull main::$1 = stackpull(signed word)

View File

@ -1,5 +1,5 @@
Calling convention STACK_CALL adding prepare/execute/finalize for call printline
Calling convention STACK_CALL adding prepare/execute/finalize for call main
Calling convention __stackcall adding prepare/execute/finalize for call printline
Calling convention __stackcall adding prepare/execute/finalize for call main
CONTROL FLOW GRAPH SSA

View File

@ -1,7 +1,7 @@
Converting variable modified inside __stackcall procedure main() to load/store val
Inlined call call __init
Converting PHI-variable modified inside __stackcall procedure main() to load/store val
Calling convention STACK_CALL adding prepare/execute/finalize for call printline
Calling convention STACK_CALL adding prepare/execute/finalize for call main
Calling convention __stackcall adding prepare/execute/finalize for call printline
Calling convention __stackcall adding prepare/execute/finalize for call main
CONTROL FLOW GRAPH SSA

View File

@ -1,11 +1,11 @@
Converting variable modified inside __stackcall procedure main() to load/store val
Inlined call call __init
Converting PHI-variable modified inside __stackcall procedure main() to load/store val
Calling convention STACK_CALL adding prepare/execute/finalize for call pval
Calling convention STACK_CALL adding prepare/execute/finalize for call printother
Calling convention STACK_CALL adding prepare/execute/finalize for call ival
Calling convention STACK_CALL adding prepare/execute/finalize for call printval
Calling convention STACK_CALL adding prepare/execute/finalize for call incval
Calling convention STACK_CALL adding prepare/execute/finalize for call main
Calling convention __stackcall adding prepare/execute/finalize for call pval
Calling convention __stackcall adding prepare/execute/finalize for call printother
Calling convention __stackcall adding prepare/execute/finalize for call ival
Calling convention __stackcall adding prepare/execute/finalize for call printval
Calling convention __stackcall adding prepare/execute/finalize for call incval
Calling convention __stackcall adding prepare/execute/finalize for call main
CONTROL FLOW GRAPH SSA

View File

@ -1198,9 +1198,9 @@ main::@4: scope:[main] from main::@2
main::@5: scope:[main] from main::@4
main::i#7 = phi( main::@4/main::i#8 )
main::pStar#3 = phi( main::@4/main::pStar#7 )
main::$8 = (byte*)main::pStar#3
main::$5 = main::$8 + OFFSET_STRUCT_$0_STAR_X
printf_uchar::uvalue#0 = *main::$5
main::$5 = (byte*)main::pStar#3
main::$3 = main::$5 + OFFSET_STRUCT_$0_STAR_X
printf_uchar::uvalue#0 = *main::$3
printf_uchar::format_min_length#0 = 0
printf_uchar::format_justify_left#0 = 0
printf_uchar::format_sign_always#0 = 0
@ -1218,9 +1218,9 @@ main::@6: scope:[main] from main::@5
main::@7: scope:[main] from main::@6
main::i#5 = phi( main::@6/main::i#6 )
main::pStar#4 = phi( main::@6/main::pStar#8 )
main::$10 = (byte*)main::pStar#4
main::$6 = main::$10 + OFFSET_STRUCT_$0_STAR_Y
printf_uchar::uvalue#1 = *main::$6
main::$6 = (byte*)main::pStar#4
main::$4 = main::$6 + OFFSET_STRUCT_$0_STAR_Y
printf_uchar::uvalue#1 = *main::$4
printf_uchar::format_min_length#1 = 0
printf_uchar::format_justify_left#1 = 0
printf_uchar::format_sign_always#1 = 0
@ -1406,10 +1406,10 @@ byte gotoxy::y#5
byte gotoxy::y#6
void main()
bool~ main::$1
byte*~ main::$10
byte*~ main::$3
byte*~ main::$4
byte*~ main::$5
byte*~ main::$6
byte*~ main::$8
byte main::i
byte main::i#0
byte main::i#1
@ -2849,15 +2849,15 @@ Successful SSA optimization Pass2ConstantIfs
Consolidated constant strings into main::s
Successful SSA optimization Pass2ConstantStringConsolidation
Rewriting conditional comparison [199] if(gotoxy::y#3<=$19) goto gotoxy::@1
Converting *(pointer+n) to pointer[n] [405] printf_uchar::uvalue#0 = *main::$5 -- main::$8[OFFSET_STRUCT_$0_STAR_X]
Converting *(pointer+n) to pointer[n] [417] printf_uchar::uvalue#1 = *main::$6 -- main::$10[OFFSET_STRUCT_$0_STAR_Y]
Converting *(pointer+n) to pointer[n] [405] printf_uchar::uvalue#0 = *main::$3 -- main::$5[OFFSET_STRUCT_$0_STAR_X]
Converting *(pointer+n) to pointer[n] [417] printf_uchar::uvalue#1 = *main::$4 -- main::$6[OFFSET_STRUCT_$0_STAR_Y]
Successful SSA optimization Pass2InlineDerefIdx
Simplifying expression containing zero (byte*)&printf_buffer in [297] *((byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_SIGN) = printf_uint::$2
Simplifying expression containing zero (byte*)&printf_buffer in [302] printf_number_buffer::buffer_sign#0 = *((byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_SIGN)
Simplifying expression containing zero (byte*)&printf_buffer in [318] *((byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_SIGN) = printf_uchar::$2
Simplifying expression containing zero (byte*)&printf_buffer in [323] printf_number_buffer::buffer_sign#1 = *((byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_SIGN)
Simplifying expression containing zero main::$8 in [404] main::$5 = main::$8 + OFFSET_STRUCT_$0_STAR_X
Simplifying expression containing zero main::$8 in [405] printf_uchar::uvalue#0 = main::$8[OFFSET_STRUCT_$0_STAR_X]
Simplifying expression containing zero main::$5 in [404] main::$3 = main::$5 + OFFSET_STRUCT_$0_STAR_X
Simplifying expression containing zero main::$5 in [405] printf_uchar::uvalue#0 = main::$5[OFFSET_STRUCT_$0_STAR_X]
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable memcpy::return#2 and assignment [161] memcpy::return#2 = memcpy::destination#2
Eliminating unused variable memcpy::return#3 and assignment [163] memcpy::return#3 = memcpy::destination#2
@ -2866,8 +2866,8 @@ Eliminating unused variable memset::return#3 and assignment [167] memset::return
Eliminating unused variable printf_number_buffer::format_sign_always#1 and assignment [211] printf_number_buffer::format_sign_always#1 = printf_uchar::format_sign_always#2
Eliminating unused variable printf_number_buffer::format_radix#1 and assignment [214] printf_number_buffer::format_radix#1 = printf_uchar::format_radix#2
Eliminating unused variable strupr::return#2 and assignment [251] strupr::return#2 = strupr::str#0
Eliminating unused variable main::$5 and assignment [262] main::$5 = main::$8
Eliminating unused variable main::$6 and assignment [267] main::$6 = main::$10 + OFFSET_STRUCT_$0_STAR_Y
Eliminating unused variable main::$3 and assignment [262] main::$3 = main::$5
Eliminating unused variable main::$4 and assignment [267] main::$4 = main::$6 + OFFSET_STRUCT_$0_STAR_Y
Eliminating unused constant uctoa::max_digits#0
Eliminating unused constant uctoa::digit_values#0
Eliminating unused constant utoa::max_digits#0
@ -3013,8 +3013,8 @@ Inlining Noop Cast [7] memcpy::$2 = (byte*)memcpy::source#2 keeping memcpy::sour
Inlining Noop Cast [17] memset::$4 = (byte*)memset::str#3 keeping memset::str#3
Inlining Noop Cast [19] memset::dst#0 = (byte*)memset::str#3 keeping memset::str#3
Inlining Noop Cast [199] printf_number_buffer::$25 = (signed byte)printf_number_buffer::format_min_length#2 keeping printf_number_buffer::format_min_length#2
Inlining Noop Cast [226] main::$8 = (byte*)main::pStar#2 keeping main::pStar#2
Inlining Noop Cast [230] main::$10 = (byte*)main::pStar#2 keeping main::pStar#2
Inlining Noop Cast [226] main::$5 = (byte*)main::pStar#2 keeping main::pStar#2
Inlining Noop Cast [230] main::$6 = (byte*)main::pStar#2 keeping main::pStar#2
Successful SSA optimization Pass2NopCastInlining
Rewriting multiplication to use shift [75] utoa::$10 = utoa::digit#2 * SIZEOF_WORD
Rewriting multiplication to use shift and addition[117] gotoxy::line_offset#0 = gotoxy::$7 * $28

View File

@ -0,0 +1,58 @@
// Test combining unwind structs with classic structs
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label SCREEN = $400
main: {
.label p1 = 2
// p1 = { 1, 2 }
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// SCREEN[0] = p1
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN-1,y
dey
bne !-
// p2 = p1
lda.z p1
ldx p1+OFFSET_STRUCT_POINT_Y
// SCREEN[2] = p2
sta SCREEN+2*SIZEOF_STRUCT_POINT
stx SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y
// p1.x = 3
// Set in classic struct
lda #3
sta.z p1
// SCREEN[4] = p1
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN+4*SIZEOF_STRUCT_POINT-1,y
dey
bne !-
// SCREEN[6] = p2
lda #4
sta SCREEN+6*SIZEOF_STRUCT_POINT
stx SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y
// p1 = p2
sta.z p1
stx p1+OFFSET_STRUCT_POINT_Y
// SCREEN[8] = p1
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN+8*SIZEOF_STRUCT_POINT-1,y
dey
bne !-
// }
rts
}
__0: .byte 1, 2

View File

@ -0,0 +1,20 @@
void main()
main: scope:[main] from
[0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT)
[1] *SCREEN = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
[2] main::p2_x#0 = *((byte*)&main::p1)
[3] main::p2_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)
[4] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT) = main::p2_x#0
[5] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
[6] *((byte*)&main::p1) = 3
[7] *(SCREEN+4*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
[8] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT) = 4
[9] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
[10] *((byte*)&main::p1) = 4
[11] *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
[12] *(SCREEN+8*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
to:main::@return
main::@return: scope:[main] from main
[13] return
to:@return

View File

@ -0,0 +1,423 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
*(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT)
main::p1 = struct-unwound {*(&main::p1)}
main::$0 = 0 * SIZEOF_STRUCT_POINT
SCREEN[main::$0] = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
main::p2_x#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_X)
main::p2_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)
main::$1 = 2 * SIZEOF_STRUCT_POINT
main::$5 = (byte*)SCREEN + main::$1
main::$5[OFFSET_STRUCT_POINT_X] = main::p2_x#0
main::$6 = (byte*)SCREEN + main::$1
main::$6[OFFSET_STRUCT_POINT_Y] = main::p2_y#0
*((byte*)&main::p1+OFFSET_STRUCT_POINT_X) = 3
main::$2 = 4 * SIZEOF_STRUCT_POINT
SCREEN[main::$2] = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
main::p2_x#1 = 4
main::$3 = 6 * SIZEOF_STRUCT_POINT
main::$7 = (byte*)SCREEN + main::$3
main::$7[OFFSET_STRUCT_POINT_X] = main::p2_x#1
main::$8 = (byte*)SCREEN + main::$3
main::$8[OFFSET_STRUCT_POINT_Y] = main::p2_y#0
*((byte*)&main::p1+OFFSET_STRUCT_POINT_X) = main::p2_x#1
*((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
main::p1 = struct-unwound {*((byte*)&main::p1+OFFSET_STRUCT_POINT_X), *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)}
main::$4 = 8 * SIZEOF_STRUCT_POINT
SCREEN[main::$4] = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
to:main::@return
main::@return: scope:[main] from main
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
const struct Point $0 = { x: 1, y: 2 }
const byte OFFSET_STRUCT_POINT_X = 0
const byte OFFSET_STRUCT_POINT_Y = 1
const nomodify struct Point* SCREEN = (struct Point*)$400
const byte SIZEOF_STRUCT_POINT = 2
void __start()
void main()
number~ main::$0
number~ main::$1
number~ main::$2
number~ main::$3
number~ main::$4
byte*~ main::$5
byte*~ main::$6
byte*~ main::$7
byte*~ main::$8
struct Point main::p1 loadstore
byte main::p2_x
byte main::p2_x#0
byte main::p2_x#1
byte main::p2_y
byte main::p2_y#0
Adding number conversion cast (unumber) 0 in main::$0 = 0 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) main::$0 in main::$0 = (unumber)0 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) 2 in main::$1 = 2 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) main::$1 in main::$1 = (unumber)2 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) 3 in *((byte*)&main::p1+OFFSET_STRUCT_POINT_X) = 3
Adding number conversion cast (unumber) 4 in main::$2 = 4 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) main::$2 in main::$2 = (unumber)4 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) 4 in main::p2_x#1 = 4
Adding number conversion cast (unumber) 6 in main::$3 = 6 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) main::$3 in main::$3 = (unumber)6 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) 8 in main::$4 = 8 * SIZEOF_STRUCT_POINT
Adding number conversion cast (unumber) main::$4 in main::$4 = (unumber)8 * SIZEOF_STRUCT_POINT
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((byte*)&main::p1+OFFSET_STRUCT_POINT_X) = (unumber)3
Inlining cast main::p2_x#1 = (unumber)4
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (struct Point*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 2
Simplifying constant integer cast 3
Simplifying constant integer cast 4
Simplifying constant integer cast 4
Simplifying constant integer cast 6
Simplifying constant integer cast 8
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 0
Finalized unsigned number type 2
Finalized unsigned number type 3
Finalized unsigned number type 4
Finalized unsigned number type 4
Finalized unsigned number type 6
Finalized unsigned number type 8
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in main::$0 = 0 * SIZEOF_STRUCT_POINT
Inferred type updated to byte in main::$1 = 2 * SIZEOF_STRUCT_POINT
Inferred type updated to byte in main::$2 = 4 * SIZEOF_STRUCT_POINT
Inferred type updated to byte in main::$3 = 6 * SIZEOF_STRUCT_POINT
Inferred type updated to byte in main::$4 = 8 * SIZEOF_STRUCT_POINT
Removing C-classic struct-unwound assignment [1] main::p1 = struct-unwound {*(&main::p1)}
Removing C-classic struct-unwound assignment [22] main::p1 = struct-unwound {*((byte*)&main::p1+OFFSET_STRUCT_POINT_X), *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)}
Constant right-side identified [2] main::$0 = 0 * SIZEOF_STRUCT_POINT
Constant right-side identified [6] main::$1 = 2 * SIZEOF_STRUCT_POINT
Constant right-side identified [12] main::$2 = 4 * SIZEOF_STRUCT_POINT
Constant right-side identified [15] main::$3 = 6 * SIZEOF_STRUCT_POINT
Constant right-side identified [23] main::$4 = 8 * SIZEOF_STRUCT_POINT
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::$0 = 0*SIZEOF_STRUCT_POINT
Constant main::$1 = 2*SIZEOF_STRUCT_POINT
Constant main::$2 = 4*SIZEOF_STRUCT_POINT
Constant main::p2_x#1 = 4
Constant main::$3 = 6*SIZEOF_STRUCT_POINT
Constant main::$4 = 8*SIZEOF_STRUCT_POINT
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero 0*SIZEOF_STRUCT_POINT in
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero SCREEN in [3] SCREEN[main::$0] = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
Simplifying expression containing zero (byte*)&main::p1 in [4] main::p2_x#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero main::$5 in [8] main::$5[OFFSET_STRUCT_POINT_X] = main::p2_x#0
Simplifying expression containing zero (byte*)&main::p1 in [11] *((byte*)&main::p1+OFFSET_STRUCT_POINT_X) = 3
Simplifying expression containing zero main::$7 in [17] main::$7[OFFSET_STRUCT_POINT_X] = main::p2_x#1
Simplifying expression containing zero (byte*)&main::p1 in [20] *((byte*)&main::p1+OFFSET_STRUCT_POINT_X) = main::p2_x#1
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant main::$0
Eliminating unused constant OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
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
Constant right-side identified [4] main::$5 = (byte*)SCREEN + main::$1
Constant right-side identified [6] main::$6 = (byte*)SCREEN + main::$1
Constant right-side identified [10] main::$7 = (byte*)SCREEN + main::$3
Constant right-side identified [12] main::$8 = (byte*)SCREEN + main::$3
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::$5 = (byte*)SCREEN+main::$1
Constant main::$6 = (byte*)SCREEN+main::$1
Constant main::$7 = (byte*)SCREEN+main::$3
Constant main::$8 = (byte*)SCREEN+main::$3
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings main::p2_x#1
Constant inlined main::$1 = 2*SIZEOF_STRUCT_POINT
Constant inlined main::$2 = 4*SIZEOF_STRUCT_POINT
Constant inlined main::$5 = (byte*)SCREEN+2*SIZEOF_STRUCT_POINT
Constant inlined main::$6 = (byte*)SCREEN+2*SIZEOF_STRUCT_POINT
Constant inlined main::$3 = 6*SIZEOF_STRUCT_POINT
Constant inlined main::$4 = 8*SIZEOF_STRUCT_POINT
Constant inlined main::$7 = (byte*)SCREEN+6*SIZEOF_STRUCT_POINT
Constant inlined main::p2_x#1 = 4
Constant inlined main::$8 = (byte*)SCREEN+6*SIZEOF_STRUCT_POINT
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y)
Consolidated array index constant in *(SCREEN+4*SIZEOF_STRUCT_POINT)
Consolidated array index constant in *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y)
Consolidated array index constant in *(SCREEN+8*SIZEOF_STRUCT_POINT)
Successful SSA optimization Pass2ConstantAdditionElimination
CALL GRAPH
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT)
[1] *SCREEN = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
[2] main::p2_x#0 = *((byte*)&main::p1)
[3] main::p2_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)
[4] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT) = main::p2_x#0
[5] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
[6] *((byte*)&main::p1) = 3
[7] *(SCREEN+4*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
[8] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT) = 4
[9] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
[10] *((byte*)&main::p1) = 4
[11] *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) = main::p2_y#0
[12] *(SCREEN+8*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
to:main::@return
main::@return: scope:[main] from main
[13] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
struct Point main::p1 loadstore
byte main::p2_x
byte main::p2_x#0 2.0
byte main::p2_y
byte main::p2_y#0 1.0
Initial phi equivalence classes
Added variable main::p2_x#0 to live range equivalence class [ main::p2_x#0 ]
Added variable main::p2_y#0 to live range equivalence class [ main::p2_y#0 ]
Added variable main::p1 to live range equivalence class [ main::p1 ]
Complete equivalence classes
[ main::p2_x#0 ]
[ main::p2_y#0 ]
[ main::p1 ]
Allocated zp[1]:2 [ main::p2_x#0 ]
Allocated zp[1]:3 [ main::p2_y#0 ]
Allocated zp[2]:4 [ main::p1 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 ] ( [ main::p1 ] { } ) always clobbers reg byte a reg byte y
Statement [1] *SCREEN = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 ] ( [ main::p1 ] { } ) always clobbers reg byte a reg byte y
Statement [6] *((byte*)&main::p1) = 3 [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::p2_y#0 ]
Statement [7] *(SCREEN+4*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte y as potential for zp[1]:3 [ main::p2_y#0 ]
Statement [8] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT) = 4 [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a
Statement [10] *((byte*)&main::p1) = 4 [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a
Statement [12] *(SCREEN+8*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ ] ( [ ] { } ) always clobbers reg byte a reg byte y
Statement [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 ] ( [ main::p1 ] { } ) always clobbers reg byte a reg byte y
Statement [1] *SCREEN = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 ] ( [ main::p1 ] { } ) always clobbers reg byte a reg byte y
Statement [6] *((byte*)&main::p1) = 3 [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a
Statement [7] *(SCREEN+4*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a reg byte y
Statement [8] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT) = 4 [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a
Statement [10] *((byte*)&main::p1) = 4 [ main::p1 main::p2_y#0 ] ( [ main::p1 main::p2_y#0 ] { } ) always clobbers reg byte a
Statement [12] *(SCREEN+8*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ ] ( [ ] { } ) always clobbers reg byte a reg byte y
Potential registers zp[1]:2 [ main::p2_x#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ main::p2_y#0 ] : zp[1]:3 , reg byte x ,
Potential registers zp[2]:4 [ main::p1 ] : zp[2]:4 ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 2: zp[1]:2 [ main::p2_x#0 ] 1: zp[1]:3 [ main::p2_y#0 ] 0: zp[2]:4 [ main::p1 ]
Uplift Scope [Point]
Uplift Scope []
Uplifting [main] best 112 combination reg byte a [ main::p2_x#0 ] reg byte x [ main::p2_y#0 ] zp[2]:4 [ main::p1 ]
Uplifting [Point] best 112 combination
Uplifting [] best 112 combination
Allocated (was zp[2]:4) zp[2]:2 [ main::p1 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test combining unwind structs with classic structs
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label SCREEN = $400
// main
main: {
.label p1 = 2
// [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// [1] *SCREEN = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN-1,y
dey
bne !-
// [2] main::p2_x#0 = *((byte*)&main::p1) -- vbuaa=_deref_pbuc1
lda.z p1
// [3] main::p2_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx p1+OFFSET_STRUCT_POINT_Y
// [4] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT) = main::p2_x#0 -- _deref_pbuc1=vbuaa
sta SCREEN+2*SIZEOF_STRUCT_POINT
// [5] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0 -- _deref_pbuc1=vbuxx
stx SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&main::p1) = 3 -- _deref_pbuc1=vbuc2
// Set in classic struct
lda #3
sta.z p1
// [7] *(SCREEN+4*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN+4*SIZEOF_STRUCT_POINT-1,y
dey
bne !-
// [8] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT) = 4 -- _deref_pbuc1=vbuc2
lda #4
sta SCREEN+6*SIZEOF_STRUCT_POINT
// [9] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0 -- _deref_pbuc1=vbuxx
stx SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)&main::p1) = 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p1
// [11] *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) = main::p2_y#0 -- _deref_pbuc1=vbuxx
stx p1+OFFSET_STRUCT_POINT_Y
// [12] *(SCREEN+8*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN+8*SIZEOF_STRUCT_POINT-1,y
dey
bne !-
jmp __breturn
// main::@return
__breturn:
// [13] return
rts
}
// File Data
__0: .byte 1, 2
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #4
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const struct Point $0 = { x: 1, y: 2 }
const byte OFFSET_STRUCT_POINT_Y = 1
const nomodify struct Point* SCREEN = (struct Point*) 1024
const byte SIZEOF_STRUCT_POINT = 2
void main()
struct Point main::p1 loadstore zp[2]:2
byte main::p2_x
byte main::p2_x#0 reg byte a 2.0
byte main::p2_y
byte main::p2_y#0 reg byte x 1.0
reg byte a [ main::p2_x#0 ]
reg byte x [ main::p2_y#0 ]
zp[2]:2 [ main::p1 ]
FINAL ASSEMBLER
Score: 107
// File Comments
// Test combining unwind structs with classic structs
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label SCREEN = $400
// main
main: {
.label p1 = 2
// p1 = { 1, 2 }
// [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// SCREEN[0] = p1
// [1] *SCREEN = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN-1,y
dey
bne !-
// p2 = p1
// [2] main::p2_x#0 = *((byte*)&main::p1) -- vbuaa=_deref_pbuc1
lda.z p1
// [3] main::p2_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx p1+OFFSET_STRUCT_POINT_Y
// SCREEN[2] = p2
// [4] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT) = main::p2_x#0 -- _deref_pbuc1=vbuaa
sta SCREEN+2*SIZEOF_STRUCT_POINT
// [5] *((byte*)SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0 -- _deref_pbuc1=vbuxx
stx SCREEN+2*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y
// p1.x = 3
// [6] *((byte*)&main::p1) = 3 -- _deref_pbuc1=vbuc2
// Set in classic struct
lda #3
sta.z p1
// SCREEN[4] = p1
// [7] *(SCREEN+4*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN+4*SIZEOF_STRUCT_POINT-1,y
dey
bne !-
// SCREEN[6] = p2
// [8] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT) = 4 -- _deref_pbuc1=vbuc2
lda #4
sta SCREEN+6*SIZEOF_STRUCT_POINT
// [9] *((byte*)SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = main::p2_y#0 -- _deref_pbuc1=vbuxx
stx SCREEN+6*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y
// p1 = p2
// [10] *((byte*)&main::p1) = 4 -- _deref_pbuc1=vbuc2
sta.z p1
// [11] *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) = main::p2_y#0 -- _deref_pbuc1=vbuxx
stx p1+OFFSET_STRUCT_POINT_Y
// SCREEN[8] = p1
// [12] *(SCREEN+8*SIZEOF_STRUCT_POINT) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta SCREEN+8*SIZEOF_STRUCT_POINT-1,y
dey
bne !-
// main::@return
// }
// [13] return
rts
}
// File Data
__0: .byte 1, 2

View File

@ -0,0 +1,14 @@
const struct Point $0 = { x: 1, y: 2 }
const byte OFFSET_STRUCT_POINT_Y = 1
const nomodify struct Point* SCREEN = (struct Point*) 1024
const byte SIZEOF_STRUCT_POINT = 2
void main()
struct Point main::p1 loadstore zp[2]:2
byte main::p2_x
byte main::p2_x#0 reg byte a 2.0
byte main::p2_y
byte main::p2_y#0 reg byte x 1.0
reg byte a [ main::p2_x#0 ]
reg byte x [ main::p2_y#0 ]
zp[2]:2 [ main::p1 ]

View File

@ -0,0 +1,86 @@
// Test combining unwind structs with classic structs
// Function calls parameter passing
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label SCREEN = $400
main: {
.const p2_x = 3
.const p2_y = 4
.label p1 = 3
// p1 = { 1, 2 }
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// print1(p1, 0)
ldy.z p1
ldx p1+OFFSET_STRUCT_POINT_Y
// Pass classic struct to function taking unwound struct
lda #0
jsr print1
// print2(p1, 2)
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta print2.p-1,y
dey
bne !-
// Pass classic struct to function taking classic struct
lda #2
jsr print2
// print1(p2, 4)
// Pass unwound struct to function taking unwound struct
ldx #p2_y
ldy #p2_x
lda #4
jsr print1
// print2(p2, 6)
lda #p2_x
sta.z print2.p
lda #p2_y
sta print2.p+OFFSET_STRUCT_POINT_Y
// Pass unwound struct to function taking classic struct
lda #6
jsr print2
// }
rts
}
// Function taking unwound struct as parameter
// print1(byte register(Y) p_x, byte register(X) p_y, byte register(A) idx)
print1: {
.label __0 = 2
// SCREEN[idx] = p
asl
sta.z __0
tya
ldy.z __0
sta SCREEN,y
txa
sta SCREEN+OFFSET_STRUCT_POINT_Y,y
// }
rts
}
// Function taking classic struct as parameter
// print2(struct Point zp(5) p, byte register(A) idx)
print2: {
.label p = 5
// SCREEN[idx] = p
asl
tay
ldx #0
!:
lda.z p,x
sta SCREEN,y
iny
inx
cpx #SIZEOF_STRUCT_POINT
bne !-
// }
rts
}
__0: .byte 1, 2

View File

@ -0,0 +1,47 @@
void main()
main: scope:[main] from
[0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT)
[1] print1::p_x#0 = *((byte*)&main::p1)
[2] print1::p_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)
[3] call print1
to:main::@1
main::@1: scope:[main] from main
[4] *(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
[5] call print2
to:main::@2
main::@2: scope:[main] from main::@1
[6] phi()
[7] call print1
to:main::@3
main::@3: scope:[main] from main::@2
[8] *((byte*)&print2::p) = main::p2_x
[9] *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y
[10] call print2
to:main::@return
main::@return: scope:[main] from main::@3
[11] return
to:@return
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
print1: scope:[print1] from main main::@2
[12] print1::p_y#2 = phi( main/print1::p_y#0, main::@2/main::p2_y )
[12] print1::p_x#2 = phi( main/print1::p_x#0, main::@2/main::p2_x )
[12] print1::idx#2 = phi( main/0, main::@2/4 )
[13] print1::$0 = print1::idx#2 << 1
[14] ((byte*)SCREEN)[print1::$0] = print1::p_x#2
[15] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2
to:print1::@return
print1::@return: scope:[print1] from print1
[16] return
to:@return
void print2(struct Point print2::p , byte print2::idx)
print2: scope:[print2] from main::@1 main::@3
[17] print2::idx#2 = phi( main::@1/2, main::@3/6 )
[18] print2::$0 = print2::idx#2 << 1
[19] SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT)
to:print2::@return
print2::@return: scope:[print2] from print2
[20] return
to:@return

View File

@ -0,0 +1,660 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
*(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT)
main::p1 = struct-unwound {*(&main::p1)}
print1::p_x#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_X)
print1::p_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)
print1::idx#0 = 0
call print1
to:main::@1
main::@1: scope:[main] from main
*(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
print2::p = struct-unwound {*(&print2::p)}
print2::idx#0 = 2
call print2
to:main::@2
main::@2: scope:[main] from main::@1
main::p2#0 = struct-unwound {main::p2_x, main::p2_y}
print1::p_x#1 = main::p2_x
print1::p_y#1 = main::p2_y
print1::idx#1 = 4
call print1
to:main::@3
main::@3: scope:[main] from main::@2
*((byte*)&print2::p+OFFSET_STRUCT_POINT_X) = main::p2_x
*((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y
print2::p = struct-unwound {*((byte*)&print2::p+OFFSET_STRUCT_POINT_X), *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y)}
print2::idx#1 = 6
call print2
to:main::@4
main::@4: scope:[main] from main::@3
to:main::@return
main::@return: scope:[main] from main::@4
return
to:@return
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
print1: scope:[print1] from main main::@2
print1::p_y#2 = phi( main/print1::p_y#0, main::@2/print1::p_y#1 )
print1::p_x#2 = phi( main/print1::p_x#0, main::@2/print1::p_x#1 )
print1::idx#2 = phi( main/print1::idx#0, main::@2/print1::idx#1 )
print1::$0 = print1::idx#2 * SIZEOF_STRUCT_POINT
((byte*)SCREEN+OFFSET_STRUCT_POINT_X)[print1::$0] = print1::p_x#2
((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2
to:print1::@return
print1::@return: scope:[print1] from print1
return
to:@return
void print2(struct Point print2::p , byte print2::idx)
print2: scope:[print2] from main::@1 main::@3
print2::idx#2 = phi( main::@1/print2::idx#0, main::@3/print2::idx#1 )
print2::$0 = print2::idx#2 * SIZEOF_STRUCT_POINT
SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT)
to:print2::@return
print2::@return: scope:[print2] from print2
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
const struct Point $0 = { x: 1, y: 2 }
const byte OFFSET_STRUCT_POINT_X = 0
const byte OFFSET_STRUCT_POINT_Y = 1
const nomodify struct Point* SCREEN = (struct Point*)$400
const byte SIZEOF_STRUCT_POINT = 2
void __start()
void main()
struct Point main::p1 loadstore
struct Point main::p2
struct Point main::p2#0
const byte main::p2_x = 3
const byte main::p2_y = 4
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
byte~ print1::$0
byte print1::idx
byte print1::idx#0
byte print1::idx#1
byte print1::idx#2
struct Point print1::p
byte print1::p_x
byte print1::p_x#0
byte print1::p_x#1
byte print1::p_x#2
byte print1::p_y
byte print1::p_y#0
byte print1::p_y#1
byte print1::p_y#2
void print2(struct Point print2::p , byte print2::idx)
byte~ print2::$0
byte print2::idx
byte print2::idx#0
byte print2::idx#1
byte print2::idx#2
struct Point print2::p loadstore
Adding number conversion cast (unumber) 0 in print1::idx#0 = 0
Adding number conversion cast (unumber) 2 in print2::idx#0 = 2
Adding number conversion cast (unumber) 4 in print1::idx#1 = 4
Adding number conversion cast (unumber) 6 in print2::idx#1 = 6
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast print1::idx#0 = (unumber)0
Inlining cast print2::idx#0 = (unumber)2
Inlining cast print1::idx#1 = (unumber)4
Inlining cast print2::idx#1 = (unumber)6
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (struct Point*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 2
Simplifying constant integer cast 4
Simplifying constant integer cast 6
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 0
Finalized unsigned number type 2
Finalized unsigned number type 4
Finalized unsigned number type 6
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [1] main::p1 = struct-unwound {*(&main::p1)}
Removing C-classic struct-unwound assignment [7] print2::p = struct-unwound {*(&print2::p)}
Removing C-classic struct-unwound assignment [17] print2::p = struct-unwound {*((byte*)&print2::p+OFFSET_STRUCT_POINT_X), *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y)}
Constant print1::idx#0 = 0
Constant print2::idx#0 = 2
Constant print1::p_x#1 = main::p2_x
Constant print1::p_y#1 = main::p2_y
Constant print1::idx#1 = 4
Constant print2::idx#1 = 6
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)&main::p1 in [2] print1::p_x#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&print2::p in [15] *((byte*)&print2::p+OFFSET_STRUCT_POINT_X) = main::p2_x
Simplifying expression containing zero (byte*)SCREEN in [23] ((byte*)SCREEN+OFFSET_STRUCT_POINT_X)[print1::$0] = print1::p_x#2
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable main::p2#0 and assignment [6] main::p2#0 = struct-unwound {main::p2_x, main::p2_y}
Eliminating unused constant OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
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
Rewriting multiplication to use shift [12] print1::$0 = print1::idx#2 * SIZEOF_STRUCT_POINT
Rewriting multiplication to use shift [17] print2::$0 = print2::idx#2 * SIZEOF_STRUCT_POINT
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings print1::idx#0
Inlining constant with var siblings print1::p_x#1
Inlining constant with var siblings print1::p_y#1
Inlining constant with var siblings print1::idx#1
Inlining constant with var siblings print2::idx#0
Inlining constant with var siblings print2::idx#1
Constant inlined print1::idx#1 = 4
Constant inlined print1::idx#0 = 0
Constant inlined print1::p_x#1 = main::p2_x
Constant inlined print1::p_y#1 = main::p2_y
Constant inlined print2::idx#0 = 2
Constant inlined print2::idx#1 = 6
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@4
CALL GRAPH
Calls in [main] to print1:5 print2:7 print1:9 print2:12
Created 4 initial phi equivalence classes
Coalesced [3] print1::p_x#3 = print1::p_x#0
Coalesced [4] print1::p_y#3 = print1::p_y#0
Coalesced down to 4 phi equivalence classes
Culled Empty Block label main::@4
Adding NOP phi() at start of main::@2
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT)
[1] print1::p_x#0 = *((byte*)&main::p1)
[2] print1::p_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y)
[3] call print1
to:main::@1
main::@1: scope:[main] from main
[4] *(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT)
[5] call print2
to:main::@2
main::@2: scope:[main] from main::@1
[6] phi()
[7] call print1
to:main::@3
main::@3: scope:[main] from main::@2
[8] *((byte*)&print2::p) = main::p2_x
[9] *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y
[10] call print2
to:main::@return
main::@return: scope:[main] from main::@3
[11] return
to:@return
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
print1: scope:[print1] from main main::@2
[12] print1::p_y#2 = phi( main/print1::p_y#0, main::@2/main::p2_y )
[12] print1::p_x#2 = phi( main/print1::p_x#0, main::@2/main::p2_x )
[12] print1::idx#2 = phi( main/0, main::@2/4 )
[13] print1::$0 = print1::idx#2 << 1
[14] ((byte*)SCREEN)[print1::$0] = print1::p_x#2
[15] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2
to:print1::@return
print1::@return: scope:[print1] from print1
[16] return
to:@return
void print2(struct Point print2::p , byte print2::idx)
print2: scope:[print2] from main::@1 main::@3
[17] print2::idx#2 = phi( main::@1/2, main::@3/6 )
[18] print2::$0 = print2::idx#2 << 1
[19] SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT)
to:print2::@return
print2::@return: scope:[print2] from print2
[20] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
struct Point main::p1 loadstore
struct Point main::p2
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
byte~ print1::$0 16.5
byte print1::idx
byte print1::idx#2 11.0
struct Point print1::p
byte print1::p_x
byte print1::p_x#0 2.0
byte print1::p_x#2 6.5
byte print1::p_y
byte print1::p_y#0 4.0
byte print1::p_y#2 4.333333333333333
void print2(struct Point print2::p , byte print2::idx)
byte~ print2::$0 22.0
byte print2::idx
byte print2::idx#2 11.0
struct Point print2::p loadstore
Initial phi equivalence classes
[ print1::idx#2 ]
[ print1::p_x#2 print1::p_x#0 ]
[ print1::p_y#2 print1::p_y#0 ]
[ print2::idx#2 ]
Added variable print1::$0 to live range equivalence class [ print1::$0 ]
Added variable print2::$0 to live range equivalence class [ print2::$0 ]
Added variable main::p1 to live range equivalence class [ main::p1 ]
Added variable print2::p to live range equivalence class [ print2::p ]
Complete equivalence classes
[ print1::idx#2 ]
[ print1::p_x#2 print1::p_x#0 ]
[ print1::p_y#2 print1::p_y#0 ]
[ print2::idx#2 ]
[ print1::$0 ]
[ print2::$0 ]
[ main::p1 ]
[ print2::p ]
Allocated zp[1]:2 [ print1::idx#2 ]
Allocated zp[1]:3 [ print1::p_x#2 print1::p_x#0 ]
Allocated zp[1]:4 [ print1::p_y#2 print1::p_y#0 ]
Allocated zp[1]:5 [ print2::idx#2 ]
Allocated zp[1]:6 [ print1::$0 ]
Allocated zp[1]:7 [ print2::$0 ]
Allocated zp[2]:8 [ main::p1 ]
Allocated zp[2]:10 [ print2::p ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 print2::p ] ( [ main::p1 print2::p ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } ) always clobbers reg byte a reg byte y
Statement [4] *(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ print2::p ] ( [ print2::p ] { } ) always clobbers reg byte a reg byte y
Statement [8] *((byte*)&print2::p) = main::p2_x [ print2::p ] ( [ print2::p ] { } ) always clobbers reg byte a
Statement [9] *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y [ print2::p ] ( [ print2::p ] { } ) always clobbers reg byte a
Statement [13] print1::$0 = print1::idx#2 << 1 [ print1::p_x#2 print1::p_y#2 print1::$0 ] ( print1:3 [ main::p1 print2::p print1::p_x#2 print1::p_y#2 print1::$0 ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } print1:7 [ print2::p print1::p_x#2 print1::p_y#2 print1::$0 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:3 [ print1::p_x#2 print1::p_x#0 ]
Removing always clobbered register reg byte a as potential for zp[1]:4 [ print1::p_y#2 print1::p_y#0 ]
Statement [14] ((byte*)SCREEN)[print1::$0] = print1::p_x#2 [ print1::p_y#2 print1::$0 ] ( print1:3 [ main::p1 print2::p print1::p_y#2 print1::$0 ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } print1:7 [ print2::p print1::p_y#2 print1::$0 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:6 [ print1::$0 ]
Statement [15] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2 [ ] ( print1:3 [ main::p1 print2::p ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } print1:7 [ print2::p ] { } ) always clobbers reg byte a
Statement [18] print2::$0 = print2::idx#2 << 1 [ print2::p print2::$0 ] ( print2:5 [ print2::p print2::$0 ] { } print2:10 [ print2::p print2::$0 ] { } ) always clobbers reg byte a
Statement [19] SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT) [ print2::p ] ( print2:5 [ print2::p ] { } print2:10 [ print2::p ] { } ) always clobbers reg byte a reg byte x reg byte y
Statement [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) [ main::p1 print2::p ] ( [ main::p1 print2::p ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } ) always clobbers reg byte a reg byte y
Statement [4] *(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) [ print2::p ] ( [ print2::p ] { } ) always clobbers reg byte a reg byte y
Statement [8] *((byte*)&print2::p) = main::p2_x [ print2::p ] ( [ print2::p ] { } ) always clobbers reg byte a
Statement [9] *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y [ print2::p ] ( [ print2::p ] { } ) always clobbers reg byte a
Statement [13] print1::$0 = print1::idx#2 << 1 [ print1::p_x#2 print1::p_y#2 print1::$0 ] ( print1:3 [ main::p1 print2::p print1::p_x#2 print1::p_y#2 print1::$0 ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } print1:7 [ print2::p print1::p_x#2 print1::p_y#2 print1::$0 ] { } ) always clobbers reg byte a
Statement [14] ((byte*)SCREEN)[print1::$0] = print1::p_x#2 [ print1::p_y#2 print1::$0 ] ( print1:3 [ main::p1 print2::p print1::p_y#2 print1::$0 ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } print1:7 [ print2::p print1::p_y#2 print1::$0 ] { } ) always clobbers reg byte a
Statement [15] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2 [ ] ( print1:3 [ main::p1 print2::p ] { { print1::p_x#0 = print1::p_x#2 } { print1::p_y#0 = print1::p_y#2 } } print1:7 [ print2::p ] { } ) always clobbers reg byte a
Statement [18] print2::$0 = print2::idx#2 << 1 [ print2::p print2::$0 ] ( print2:5 [ print2::p print2::$0 ] { } print2:10 [ print2::p print2::$0 ] { } ) always clobbers reg byte a
Statement [19] SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT) [ print2::p ] ( print2:5 [ print2::p ] { } print2:10 [ print2::p ] { } ) always clobbers reg byte a reg byte x reg byte y
Potential registers zp[1]:2 [ print1::idx#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ print1::p_x#2 print1::p_x#0 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ print1::p_y#2 print1::p_y#0 ] : zp[1]:4 , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ print2::idx#2 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:6 [ print1::$0 ] : zp[1]:6 , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ print2::$0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[2]:8 [ main::p1 ] : zp[2]:8 ,
Potential registers zp[2]:10 [ print2::p ] : zp[2]:10 ,
REGISTER UPLIFT SCOPES
Uplift Scope [print1] 16.5: zp[1]:6 [ print1::$0 ] 11: zp[1]:2 [ print1::idx#2 ] 8.5: zp[1]:3 [ print1::p_x#2 print1::p_x#0 ] 8.33: zp[1]:4 [ print1::p_y#2 print1::p_y#0 ]
Uplift Scope [print2] 22: zp[1]:7 [ print2::$0 ] 11: zp[1]:5 [ print2::idx#2 ] 0: zp[2]:10 [ print2::p ]
Uplift Scope [Point]
Uplift Scope [main] 0: zp[2]:8 [ main::p1 ]
Uplift Scope []
Uplifting [print1] best 184 combination zp[1]:6 [ print1::$0 ] reg byte a [ print1::idx#2 ] reg byte y [ print1::p_x#2 print1::p_x#0 ] reg byte x [ print1::p_y#2 print1::p_y#0 ]
Limited combination testing to 100 combinations of 108 possible.
Uplifting [print2] best 170 combination reg byte y [ print2::$0 ] reg byte a [ print2::idx#2 ] zp[2]:10 [ print2::p ]
Uplifting [Point] best 170 combination
Uplifting [main] best 170 combination zp[2]:8 [ main::p1 ]
Uplifting [] best 170 combination
Attempting to uplift remaining variables inzp[1]:6 [ print1::$0 ]
Uplifting [print1] best 170 combination zp[1]:6 [ print1::$0 ]
Allocated (was zp[1]:6) zp[1]:2 [ print1::$0 ]
Allocated (was zp[2]:8) zp[2]:3 [ main::p1 ]
Allocated (was zp[2]:10) zp[2]:5 [ print2::p ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test combining unwind structs with classic structs
// Function calls parameter passing
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label SCREEN = $400
// main
main: {
.const p2_x = 3
.const p2_y = 4
.label p1 = 3
// [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// [1] print1::p_x#0 = *((byte*)&main::p1) -- vbuyy=_deref_pbuc1
ldy.z p1
// [2] print1::p_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx p1+OFFSET_STRUCT_POINT_Y
// [3] call print1
// Pass classic struct to function taking unwound struct
// [12] phi from main to print1 [phi:main->print1]
print1_from_main:
// [12] phi print1::p_y#2 = print1::p_y#0 [phi:main->print1#0] -- register_copy
// [12] phi print1::p_x#2 = print1::p_x#0 [phi:main->print1#1] -- register_copy
// [12] phi print1::idx#2 = 0 [phi:main->print1#2] -- vbuaa=vbuc1
lda #0
jsr print1
jmp __b1
// main::@1
__b1:
// [4] *(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta print2.p-1,y
dey
bne !-
// [5] call print2
// Pass classic struct to function taking classic struct
// [17] phi from main::@1 to print2 [phi:main::@1->print2]
print2_from___b1:
// [17] phi print2::idx#2 = 2 [phi:main::@1->print2#0] -- vbuaa=vbuc1
lda #2
jsr print2
// [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
__b2_from___b1:
jmp __b2
// main::@2
__b2:
// [7] call print1
// Pass unwound struct to function taking unwound struct
// [12] phi from main::@2 to print1 [phi:main::@2->print1]
print1_from___b2:
// [12] phi print1::p_y#2 = main::p2_y [phi:main::@2->print1#0] -- vbuxx=vbuc1
ldx #p2_y
// [12] phi print1::p_x#2 = main::p2_x [phi:main::@2->print1#1] -- vbuyy=vbuc1
ldy #p2_x
// [12] phi print1::idx#2 = 4 [phi:main::@2->print1#2] -- vbuaa=vbuc1
lda #4
jsr print1
jmp __b3
// main::@3
__b3:
// [8] *((byte*)&print2::p) = main::p2_x -- _deref_pbuc1=vbuc2
lda #p2_x
sta.z print2.p
// [9] *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y -- _deref_pbuc1=vbuc2
lda #p2_y
sta print2.p+OFFSET_STRUCT_POINT_Y
// [10] call print2
// Pass unwound struct to function taking classic struct
// [17] phi from main::@3 to print2 [phi:main::@3->print2]
print2_from___b3:
// [17] phi print2::idx#2 = 6 [phi:main::@3->print2#0] -- vbuaa=vbuc1
lda #6
jsr print2
jmp __breturn
// main::@return
__breturn:
// [11] return
rts
}
// print1
// Function taking unwound struct as parameter
// print1(byte register(Y) p_x, byte register(X) p_y, byte register(A) idx)
print1: {
.label __0 = 2
// [13] print1::$0 = print1::idx#2 << 1 -- vbuz1=vbuaa_rol_1
asl
sta.z __0
// [14] ((byte*)SCREEN)[print1::$0] = print1::p_x#2 -- pbuc1_derefidx_vbuz1=vbuyy
tya
ldy.z __0
sta SCREEN,y
// [15] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2 -- pbuc1_derefidx_vbuz1=vbuxx
ldy.z __0
txa
sta SCREEN+OFFSET_STRUCT_POINT_Y,y
jmp __breturn
// print1::@return
__breturn:
// [16] return
rts
}
// print2
// Function taking classic struct as parameter
// print2(struct Point zp(5) p, byte register(A) idx)
print2: {
.label p = 5
// [18] print2::$0 = print2::idx#2 << 1 -- vbuyy=vbuaa_rol_1
asl
tay
// [19] SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT) -- pssc1_derefidx_vbuyy=_deref_pssc2_memcpy_vbuc3
ldx #0
!:
lda.z p,x
sta SCREEN,y
iny
inx
cpx #SIZEOF_STRUCT_POINT
bne !-
jmp __breturn
// print2::@return
__breturn:
// [20] return
rts
}
// File Data
__0: .byte 1, 2
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy.z __0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b2_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction print1_from_main:
Removing instruction __b1:
Removing instruction print2_from___b1:
Removing instruction __b2:
Removing instruction print1_from___b2:
Removing instruction __b3:
Removing instruction print2_from___b3:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const struct Point $0 = { x: 1, y: 2 }
const byte OFFSET_STRUCT_POINT_Y = 1
const nomodify struct Point* SCREEN = (struct Point*) 1024
const byte SIZEOF_STRUCT_POINT = 2
void main()
struct Point main::p1 loadstore zp[2]:3
struct Point main::p2
const byte main::p2_x = 3
const byte main::p2_y = 4
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
byte~ print1::$0 zp[1]:2 16.5
byte print1::idx
byte print1::idx#2 reg byte a 11.0
struct Point print1::p
byte print1::p_x
byte print1::p_x#0 reg byte y 2.0
byte print1::p_x#2 reg byte y 6.5
byte print1::p_y
byte print1::p_y#0 reg byte x 4.0
byte print1::p_y#2 reg byte x 4.333333333333333
void print2(struct Point print2::p , byte print2::idx)
byte~ print2::$0 reg byte y 22.0
byte print2::idx
byte print2::idx#2 reg byte a 11.0
struct Point print2::p loadstore zp[2]:5
reg byte a [ print1::idx#2 ]
reg byte y [ print1::p_x#2 print1::p_x#0 ]
reg byte x [ print1::p_y#2 print1::p_y#0 ]
reg byte a [ print2::idx#2 ]
zp[1]:2 [ print1::$0 ]
reg byte y [ print2::$0 ]
zp[2]:3 [ main::p1 ]
zp[2]:5 [ print2::p ]
FINAL ASSEMBLER
Score: 149
// File Comments
// Test combining unwind structs with classic structs
// Function calls parameter passing
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label SCREEN = $400
// main
main: {
.const p2_x = 3
.const p2_y = 4
.label p1 = 3
// p1 = { 1, 2 }
// [0] *(&main::p1) = memcpy(*(&$0), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// print1(p1, 0)
// [1] print1::p_x#0 = *((byte*)&main::p1) -- vbuyy=_deref_pbuc1
ldy.z p1
// [2] print1::p_y#0 = *((byte*)&main::p1+OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx p1+OFFSET_STRUCT_POINT_Y
// [3] call print1
// Pass classic struct to function taking unwound struct
// [12] phi from main to print1 [phi:main->print1]
// [12] phi print1::p_y#2 = print1::p_y#0 [phi:main->print1#0] -- register_copy
// [12] phi print1::p_x#2 = print1::p_x#0 [phi:main->print1#1] -- register_copy
// [12] phi print1::idx#2 = 0 [phi:main->print1#2] -- vbuaa=vbuc1
lda #0
jsr print1
// main::@1
// print2(p1, 2)
// [4] *(&print2::p) = memcpy(*(&main::p1), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda p1-1,y
sta print2.p-1,y
dey
bne !-
// [5] call print2
// Pass classic struct to function taking classic struct
// [17] phi from main::@1 to print2 [phi:main::@1->print2]
// [17] phi print2::idx#2 = 2 [phi:main::@1->print2#0] -- vbuaa=vbuc1
lda #2
jsr print2
// [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
// main::@2
// print1(p2, 4)
// [7] call print1
// Pass unwound struct to function taking unwound struct
// [12] phi from main::@2 to print1 [phi:main::@2->print1]
// [12] phi print1::p_y#2 = main::p2_y [phi:main::@2->print1#0] -- vbuxx=vbuc1
ldx #p2_y
// [12] phi print1::p_x#2 = main::p2_x [phi:main::@2->print1#1] -- vbuyy=vbuc1
ldy #p2_x
// [12] phi print1::idx#2 = 4 [phi:main::@2->print1#2] -- vbuaa=vbuc1
lda #4
jsr print1
// main::@3
// print2(p2, 6)
// [8] *((byte*)&print2::p) = main::p2_x -- _deref_pbuc1=vbuc2
lda #p2_x
sta.z print2.p
// [9] *((byte*)&print2::p+OFFSET_STRUCT_POINT_Y) = main::p2_y -- _deref_pbuc1=vbuc2
lda #p2_y
sta print2.p+OFFSET_STRUCT_POINT_Y
// [10] call print2
// Pass unwound struct to function taking classic struct
// [17] phi from main::@3 to print2 [phi:main::@3->print2]
// [17] phi print2::idx#2 = 6 [phi:main::@3->print2#0] -- vbuaa=vbuc1
lda #6
jsr print2
// main::@return
// }
// [11] return
rts
}
// print1
// Function taking unwound struct as parameter
// print1(byte register(Y) p_x, byte register(X) p_y, byte register(A) idx)
print1: {
.label __0 = 2
// SCREEN[idx] = p
// [13] print1::$0 = print1::idx#2 << 1 -- vbuz1=vbuaa_rol_1
asl
sta.z __0
// [14] ((byte*)SCREEN)[print1::$0] = print1::p_x#2 -- pbuc1_derefidx_vbuz1=vbuyy
tya
ldy.z __0
sta SCREEN,y
// [15] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[print1::$0] = print1::p_y#2 -- pbuc1_derefidx_vbuz1=vbuxx
txa
sta SCREEN+OFFSET_STRUCT_POINT_Y,y
// print1::@return
// }
// [16] return
rts
}
// print2
// Function taking classic struct as parameter
// print2(struct Point zp(5) p, byte register(A) idx)
print2: {
.label p = 5
// SCREEN[idx] = p
// [18] print2::$0 = print2::idx#2 << 1 -- vbuyy=vbuaa_rol_1
asl
tay
// [19] SCREEN[print2::$0] = memcpy(*(&print2::p), struct Point, SIZEOF_STRUCT_POINT) -- pssc1_derefidx_vbuyy=_deref_pssc2_memcpy_vbuc3
ldx #0
!:
lda.z p,x
sta SCREEN,y
iny
inx
cpx #SIZEOF_STRUCT_POINT
bne !-
// print2::@return
// }
// [20] return
rts
}
// File Data
__0: .byte 1, 2

View File

@ -0,0 +1,34 @@
const struct Point $0 = { x: 1, y: 2 }
const byte OFFSET_STRUCT_POINT_Y = 1
const nomodify struct Point* SCREEN = (struct Point*) 1024
const byte SIZEOF_STRUCT_POINT = 2
void main()
struct Point main::p1 loadstore zp[2]:3
struct Point main::p2
const byte main::p2_x = 3
const byte main::p2_y = 4
void print1(byte print1::p_x , byte print1::p_y , byte print1::idx)
byte~ print1::$0 zp[1]:2 16.5
byte print1::idx
byte print1::idx#2 reg byte a 11.0
struct Point print1::p
byte print1::p_x
byte print1::p_x#0 reg byte y 2.0
byte print1::p_x#2 reg byte y 6.5
byte print1::p_y
byte print1::p_y#0 reg byte x 4.0
byte print1::p_y#2 reg byte x 4.333333333333333
void print2(struct Point print2::p , byte print2::idx)
byte~ print2::$0 reg byte y 22.0
byte print2::idx
byte print2::idx#2 reg byte a 11.0
struct Point print2::p loadstore zp[2]:5
reg byte a [ print1::idx#2 ]
reg byte y [ print1::p_x#2 print1::p_x#0 ]
reg byte x [ print1::p_y#2 print1::p_y#0 ]
reg byte a [ print2::idx#2 ]
zp[1]:2 [ print1::$0 ]
reg byte y [ print2::$0 ]
zp[2]:3 [ main::p1 ]
zp[2]:5 [ print2::p ]

View File

@ -0,0 +1,27 @@
// Test __varcall calling convention
// Parameter passing
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label BGCOL = $d021
// setbg(byte zp(2) col)
setbg: {
.label col = 2
// *BGCOL = col
lda.z col
sta BGCOL
// }
rts
}
main: {
// setbg(0)
lda #0
sta.z setbg.col
jsr setbg
// setbg(0x0b)
lda #$b
sta.z setbg.col
jsr setbg
// }
rts
}

View File

@ -0,0 +1,19 @@
__varcall void setbg(byte setbg::col)
setbg: scope:[setbg] from
[0] *BGCOL = setbg::col
to:setbg::@return
setbg::@return: scope:[setbg] from setbg
[1] return
to:@return
void main()
main: scope:[main] from
[2] setbg::col = 0
[3] callexecute setbg
[4] setbg::col = $b
[5] callexecute setbg
to:main::@return
main::@return: scope:[main] from main
[6] return
to:@return

221
src/test/ref/varcall-1.log Normal file
View File

@ -0,0 +1,221 @@
Converting parameter in __varcall procedure to load/store setbg::col
Calling convention __varcall adding prepare/execute/finalize for call setbg 0
Calling convention __varcall adding prepare/execute/finalize for call setbg $b
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
setbg::col = 0
callexecute setbg
setbg::col = $b
callexecute setbg
to:main::@return
main::@return: scope:[main] from main
return
to:@return
__varcall void setbg(byte setbg::col)
setbg: scope:[setbg] from
*BGCOL = setbg::col
to:setbg::@return
setbg::@return: scope:[setbg] from setbg
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
const nomodify byte* BGCOL = (byte*)$d021
void __start()
void main()
__varcall void setbg(byte setbg::col)
byte setbg::col loadstore
Adding number conversion cast (unumber) 0 in setbg::col = 0
Adding number conversion cast (unumber) $b in setbg::col = $b
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast setbg::col = (unumber)0
Inlining cast setbg::col = (unumber)$b
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53281
Simplifying constant integer cast 0
Simplifying constant integer cast $b
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 0
Finalized unsigned number type $b
Successful SSA optimization PassNFinalizeNumberTypeConversions
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
CALL GRAPH
Calls in [main] to setbg:3 setbg:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
__varcall void setbg(byte setbg::col)
setbg: scope:[setbg] from
[0] *BGCOL = setbg::col
to:setbg::@return
setbg::@return: scope:[setbg] from setbg
[1] return
to:@return
void main()
main: scope:[main] from
[2] setbg::col = 0
[3] callexecute setbg
[4] setbg::col = $b
[5] callexecute setbg
to:main::@return
main::@return: scope:[main] from main
[6] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__varcall void setbg(byte setbg::col)
byte setbg::col loadstore 7.5
Initial phi equivalence classes
Added variable setbg::col to live range equivalence class [ setbg::col ]
Complete equivalence classes
[ setbg::col ]
Allocated zp[1]:2 [ setbg::col ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *BGCOL = setbg::col [ ] ( setbg:3 [ ] { } setbg:5 [ ] { } ) always clobbers reg byte a
Statement [2] setbg::col = 0 [ setbg::col ] ( [ setbg::col ] { } ) always clobbers reg byte a
Statement [4] setbg::col = $b [ setbg::col ] ( [ setbg::col ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ setbg::col ] : zp[1]:2 ,
REGISTER UPLIFT SCOPES
Uplift Scope [setbg] 7.5: zp[1]:2 [ setbg::col ]
Uplift Scope [main]
Uplift Scope []
Uplifting [setbg] best 47 combination zp[1]:2 [ setbg::col ]
Uplifting [main] best 47 combination
Uplifting [] best 47 combination
Attempting to uplift remaining variables inzp[1]:2 [ setbg::col ]
Uplifting [setbg] best 47 combination zp[1]:2 [ setbg::col ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test __varcall calling convention
// Parameter passing
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label BGCOL = $d021
// setbg
// setbg(byte zp(2) col)
setbg: {
.label col = 2
// [0] *BGCOL = setbg::col -- _deref_pbuc1=vbuz1
lda.z col
sta BGCOL
jmp __breturn
// setbg::@return
__breturn:
// [1] return
rts
}
// main
main: {
// [2] setbg::col = 0 -- vbuz1=vbuc1
lda #0
sta.z setbg.col
// [3] callexecute setbg -- jsr
jsr setbg
// [4] setbg::col = $b -- vbuz1=vbuc1
lda #$b
sta.z setbg.col
// [5] callexecute setbg -- jsr
jsr setbg
jmp __breturn
// main::@return
__breturn:
// [6] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const nomodify byte* BGCOL = (byte*) 53281
void main()
__varcall void setbg(byte setbg::col)
byte setbg::col loadstore zp[1]:2 7.5
zp[1]:2 [ setbg::col ]
FINAL ASSEMBLER
Score: 41
// File Comments
// Test __varcall calling convention
// Parameter passing
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label BGCOL = $d021
// setbg
// setbg(byte zp(2) col)
setbg: {
.label col = 2
// *BGCOL = col
// [0] *BGCOL = setbg::col -- _deref_pbuc1=vbuz1
lda.z col
sta BGCOL
// setbg::@return
// }
// [1] return
rts
}
// main
main: {
// setbg(0)
// [2] setbg::col = 0 -- vbuz1=vbuc1
lda #0
sta.z setbg.col
// [3] callexecute setbg -- jsr
jsr setbg
// setbg(0x0b)
// [4] setbg::col = $b -- vbuz1=vbuc1
lda #$b
sta.z setbg.col
// [5] callexecute setbg -- jsr
jsr setbg
// main::@return
// }
// [6] return
rts
}
// File Data

View File

@ -0,0 +1,6 @@
const nomodify byte* BGCOL = (byte*) 53281
void main()
__varcall void setbg(byte setbg::col)
byte setbg::col loadstore zp[1]:2 7.5
zp[1]:2 [ setbg::col ]

View File

@ -0,0 +1,43 @@
// Test __varcall calling convention
// Return value
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label BGCOL = $d021
// plus(byte zp(3) a, byte zp(4) b)
plus: {
.label return = 2
.label a = 3
.label b = 4
// a+b
lda.z a
clc
adc.z b
// return a+b;
sta.z return
// }
rts
}
main: {
// *BGCOL = a
lda #1
sta BGCOL
// plus(a, 1)
sta.z plus.a
sta.z plus.b
jsr plus
// a = plus(a, 1)
lda.z plus.return
// *BGCOL = a
sta BGCOL
// plus(a, a)
sta.z plus.a
sta.z plus.b
jsr plus
// a = plus(a, a)
lda.z plus.return
// *BGCOL = a
sta BGCOL
// }
rts
}

View File

@ -0,0 +1,27 @@
__varcall byte plus(byte plus::a , byte plus::b)
plus: scope:[plus] from
[0] plus::$0 = plus::a + plus::b
[1] plus::return = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus
[2] return
to:@return
void main()
main: scope:[main] from
[3] *BGCOL = 1
[4] plus::a = 1
[5] plus::b = 1
[6] callexecute plus
[7] main::a#1 = plus::return
[8] *BGCOL = main::a#1
[9] plus::a = main::a#1
[10] plus::b = main::a#1
[11] callexecute plus
[12] main::a#2 = plus::return
[13] *BGCOL = main::a#2
to:main::@return
main::@return: scope:[main] from main
[14] return
to:@return

354
src/test/ref/varcall-2.log Normal file
View File

@ -0,0 +1,354 @@
Converting parameter in __varcall procedure to load/store plus::a
Converting parameter in __varcall procedure to load/store plus::b
Converting return in __varcall procedure to load/store plus::return
Calling convention __varcall adding prepare/execute/finalize for main::$0 = call plus main::a 1
Calling convention __varcall adding prepare/execute/finalize for main::$1 = call plus main::a main::a
Calling convention VAR_CALL adding return value assignment main::$0 = plus::return
Calling convention VAR_CALL adding return value assignment main::$1 = plus::return
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
main::a#0 = 1
*BGCOL = main::a#0
plus::a = main::a#0
plus::b = 1
callexecute plus
main::$0 = plus::return
main::a#1 = main::$0
*BGCOL = main::a#1
plus::a = main::a#1
plus::b = main::a#1
callexecute plus
main::$1 = plus::return
main::a#2 = main::$1
*BGCOL = main::a#2
to:main::@return
main::@return: scope:[main] from main
return
to:@return
__varcall byte plus(byte plus::a , byte plus::b)
plus: scope:[plus] from
plus::$0 = plus::a + plus::b
plus::return = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus
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
const nomodify byte* BGCOL = (byte*)$d021
void __start()
void main()
byte~ main::$0
byte~ main::$1
byte main::a
byte main::a#0
byte main::a#1
byte main::a#2
__varcall byte plus(byte plus::a , byte plus::b)
byte~ plus::$0
byte plus::a loadstore
byte plus::b loadstore
byte plus::return loadstore
Adding number conversion cast (unumber) 1 in plus::b = 1
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b = (unumber)1
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53281
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias candidate removed (volatile)plus::return = plus::$0
Alias main::a#1 = main::$0
Alias main::a#2 = main::$1
Successful SSA optimization Pass2AliasElimination
Alias candidate removed (volatile)plus::return = plus::$0
Constant main::a#0 = 1
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 candidate removed (volatile)plus::return = plus::$0
Inlining constant with var siblings main::a#0
Constant inlined main::a#0 = 1
Successful SSA optimization Pass2ConstantInlining
Alias candidate removed (volatile)plus::return = plus::$0
Alias candidate removed (volatile)plus::return = plus::$0
CALL GRAPH
Calls in [main] to plus:6 plus:11
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
__varcall byte plus(byte plus::a , byte plus::b)
plus: scope:[plus] from
[0] plus::$0 = plus::a + plus::b
[1] plus::return = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus
[2] return
to:@return
void main()
main: scope:[main] from
[3] *BGCOL = 1
[4] plus::a = 1
[5] plus::b = 1
[6] callexecute plus
[7] main::a#1 = plus::return
[8] *BGCOL = main::a#1
[9] plus::a = main::a#1
[10] plus::b = main::a#1
[11] callexecute plus
[12] main::a#2 = plus::return
[13] *BGCOL = main::a#2
to:main::@return
main::@return: scope:[main] from main
[14] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
byte main::a
byte main::a#1 2.6666666666666665
byte main::a#2 4.0
__varcall byte plus(byte plus::a , byte plus::b)
byte~ plus::$0 22.0
byte plus::a loadstore 3.75
byte plus::b loadstore 7.5
byte plus::return loadstore 3.75
Initial phi equivalence classes
Added variable plus::$0 to live range equivalence class [ plus::$0 ]
Added variable plus::return to live range equivalence class [ plus::return ]
Added variable plus::a to live range equivalence class [ plus::a ]
Added variable plus::b to live range equivalence class [ plus::b ]
Added variable main::a#1 to live range equivalence class [ main::a#1 ]
Added variable main::a#2 to live range equivalence class [ main::a#2 ]
Complete equivalence classes
[ plus::$0 ]
[ plus::return ]
[ plus::a ]
[ plus::b ]
[ main::a#1 ]
[ main::a#2 ]
Allocated zp[1]:2 [ plus::$0 ]
Allocated zp[1]:3 [ plus::return ]
Allocated zp[1]:4 [ plus::a ]
Allocated zp[1]:5 [ plus::b ]
Allocated zp[1]:6 [ main::a#1 ]
Allocated zp[1]:7 [ main::a#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] plus::$0 = plus::a + plus::b [ plus::$0 ] ( plus:6 [ plus::$0 ] { { main::a#1 = plus::a plus::b } } plus:11 [ plus::$0 ] { { main::a#1 = plus::a plus::b } } ) always clobbers reg byte a
Statement [3] *BGCOL = 1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [4] plus::a = 1 [ plus::a ] ( [ plus::a ] { } ) always clobbers reg byte a
Statement [5] plus::b = 1 [ plus::a plus::b ] ( [ plus::a plus::b ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ plus::$0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ plus::return ] : zp[1]:3 ,
Potential registers zp[1]:4 [ plus::a ] : zp[1]:4 ,
Potential registers zp[1]:5 [ plus::b ] : zp[1]:5 ,
Potential registers zp[1]:6 [ main::a#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::a#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [plus] 22: zp[1]:2 [ plus::$0 ] 7.5: zp[1]:5 [ plus::b ] 3.75: zp[1]:3 [ plus::return ] 3.75: zp[1]:4 [ plus::a ]
Uplift Scope [main] 4: zp[1]:7 [ main::a#2 ] 2.67: zp[1]:6 [ main::a#1 ]
Uplift Scope []
Uplifting [plus] best 95 combination reg byte a [ plus::$0 ] zp[1]:5 [ plus::b ] zp[1]:3 [ plus::return ] zp[1]:4 [ plus::a ]
Uplifting [main] best 77 combination reg byte a [ main::a#2 ] reg byte a [ main::a#1 ]
Uplifting [] best 77 combination
Attempting to uplift remaining variables inzp[1]:5 [ plus::b ]
Uplifting [plus] best 77 combination zp[1]:5 [ plus::b ]
Attempting to uplift remaining variables inzp[1]:3 [ plus::return ]
Uplifting [plus] best 77 combination zp[1]:3 [ plus::return ]
Attempting to uplift remaining variables inzp[1]:4 [ plus::a ]
Uplifting [plus] best 77 combination zp[1]:4 [ plus::a ]
Allocated (was zp[1]:3) zp[1]:2 [ plus::return ]
Allocated (was zp[1]:4) zp[1]:3 [ plus::a ]
Allocated (was zp[1]:5) zp[1]:4 [ plus::b ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test __varcall calling convention
// Return value
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label BGCOL = $d021
// plus
// plus(byte zp(3) a, byte zp(4) b)
plus: {
.label return = 2
.label a = 3
.label b = 4
// [0] plus::$0 = plus::a + plus::b -- vbuaa=vbuz1_plus_vbuz2
lda.z a
clc
adc.z b
// [1] plus::return = plus::$0 -- vbuz1=vbuaa
sta.z return
jmp __breturn
// plus::@return
__breturn:
// [2] return
rts
}
// main
main: {
// [3] *BGCOL = 1 -- _deref_pbuc1=vbuc2
lda #1
sta BGCOL
// [4] plus::a = 1 -- vbuz1=vbuc1
lda #1
sta.z plus.a
// [5] plus::b = 1 -- vbuz1=vbuc1
lda #1
sta.z plus.b
// [6] callexecute plus -- jsr
jsr plus
// [7] main::a#1 = plus::return -- vbuaa=vbuz1
lda.z plus.return
// [8] *BGCOL = main::a#1 -- _deref_pbuc1=vbuaa
sta BGCOL
// [9] plus::a = main::a#1 -- vbuz1=vbuaa
sta.z plus.a
// [10] plus::b = main::a#1 -- vbuz1=vbuaa
sta.z plus.b
// [11] callexecute plus -- jsr
jsr plus
// [12] main::a#2 = plus::return -- vbuaa=vbuz1
lda.z plus.return
// [13] *BGCOL = main::a#2 -- _deref_pbuc1=vbuaa
sta BGCOL
jmp __breturn
// main::@return
__breturn:
// [14] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #1
Removing instruction lda #1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const nomodify byte* BGCOL = (byte*) 53281
void main()
byte main::a
byte main::a#1 reg byte a 2.6666666666666665
byte main::a#2 reg byte a 4.0
__varcall byte plus(byte plus::a , byte plus::b)
byte~ plus::$0 reg byte a 22.0
byte plus::a loadstore zp[1]:3 3.75
byte plus::b loadstore zp[1]:4 7.5
byte plus::return loadstore zp[1]:2 3.75
reg byte a [ plus::$0 ]
zp[1]:2 [ plus::return ]
zp[1]:3 [ plus::a ]
zp[1]:4 [ plus::b ]
reg byte a [ main::a#1 ]
reg byte a [ main::a#2 ]
FINAL ASSEMBLER
Score: 67
// File Comments
// Test __varcall calling convention
// Return value
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label BGCOL = $d021
// plus
// plus(byte zp(3) a, byte zp(4) b)
plus: {
.label return = 2
.label a = 3
.label b = 4
// a+b
// [0] plus::$0 = plus::a + plus::b -- vbuaa=vbuz1_plus_vbuz2
lda.z a
clc
adc.z b
// return a+b;
// [1] plus::return = plus::$0 -- vbuz1=vbuaa
sta.z return
// plus::@return
// }
// [2] return
rts
}
// main
main: {
// *BGCOL = a
// [3] *BGCOL = 1 -- _deref_pbuc1=vbuc2
lda #1
sta BGCOL
// plus(a, 1)
// [4] plus::a = 1 -- vbuz1=vbuc1
sta.z plus.a
// [5] plus::b = 1 -- vbuz1=vbuc1
sta.z plus.b
// [6] callexecute plus -- jsr
jsr plus
// a = plus(a, 1)
// [7] main::a#1 = plus::return -- vbuaa=vbuz1
lda.z plus.return
// *BGCOL = a
// [8] *BGCOL = main::a#1 -- _deref_pbuc1=vbuaa
sta BGCOL
// plus(a, a)
// [9] plus::a = main::a#1 -- vbuz1=vbuaa
sta.z plus.a
// [10] plus::b = main::a#1 -- vbuz1=vbuaa
sta.z plus.b
// [11] callexecute plus -- jsr
jsr plus
// a = plus(a, a)
// [12] main::a#2 = plus::return -- vbuaa=vbuz1
lda.z plus.return
// *BGCOL = a
// [13] *BGCOL = main::a#2 -- _deref_pbuc1=vbuaa
sta BGCOL
// main::@return
// }
// [14] return
rts
}
// File Data

Some files were not shown because too many files have changed in this diff Show More