mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-26 12:49:21 +00:00
Merged 372-varcall into master.
This commit is contained in:
commit
abb946cca8
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
|
||||
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
|
||||
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
|
||||
//FRAGMENT _deref_pbuc1=vbuc2
|
||||
lda #{c2}
|
||||
sta {c1}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
|
||||
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
|
2241
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
2241
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE f8d7c2682 f8d7c43d0
|
||||
//KICKC FRAGMENT CACHE fb64e786f fb64e95eb
|
||||
//FRAGMENT vbuz1=_deref_pbuc1
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
|
8
src/main/fragment/mos6502-common/_deref_pdsc1=vdsc2.asm
Normal file
8
src/main/fragment/mos6502-common/_deref_pdsc1=vdsc2.asm
Normal 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
|
8
src/main/fragment/mos6502-common/_deref_pdsc1=vdsm1.asm
Normal file
8
src/main/fragment/mos6502-common/_deref_pdsc1=vdsm1.asm
Normal 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
|
8
src/main/fragment/mos6502-common/vdsm1=_deref_pdsc1.asm
Normal file
8
src/main/fragment/mos6502-common/vdsm1=_deref_pdsc1.asm
Normal 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
|
@ -0,0 +1,9 @@
|
||||
ldy #0
|
||||
clc
|
||||
lda ({z2}),y
|
||||
adc {m3}
|
||||
sta {m1}
|
||||
iny
|
||||
lda ({z2}),y
|
||||
adc {m3}+1
|
||||
sta {m1}+1
|
@ -0,0 +1,9 @@
|
||||
ldy #0
|
||||
clc
|
||||
lda {m2}
|
||||
adc ({z3}),y
|
||||
sta {m1}
|
||||
iny
|
||||
lda {m2}+1
|
||||
adc ({z3}),y
|
||||
sta {m1}+1
|
@ -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}
|
@ -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}
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -29,4 +29,8 @@ public class ParamValue implements RValue {
|
||||
return "param("+parameter.toString(program)+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(null);
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
135
src/main/java/dk/camelot64/kickc/passes/Pass1CallVar.java
Normal file
135
src/main/java/dk/camelot64/kickc/passes/Pass1CallVar.java
Normal 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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
246
src/test/kc/adventofcode/2020-01.c
Normal file
246
src/test/kc/adventofcode/2020-01.c
Normal 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
|
||||
};
|
1073
src/test/kc/adventofcode/2020-02.c
Normal file
1073
src/test/kc/adventofcode/2020-02.c
Normal file
File diff suppressed because it is too large
Load Diff
366
src/test/kc/adventofcode/2020-03.c
Normal file
366
src/test/kc/adventofcode/2020-03.c
Normal 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 =
|
||||
".#......##..#.....#....#.#.#..."
|
||||
".#.#...#.##.#..........#...##.."
|
||||
".........#.....#.####........#."
|
||||
".......#.#...#.#..............."
|
||||
"..#....#...#.#...#.#...#.#....."
|
||||
"...#...........#..#.........#.#"
|
||||
"....#..#....#..#..#.#...#..##.."
|
||||
"#...........#..#.....#.......#."
|
||||
"#..#...#...#.###...#...#.#...#."
|
||||
"#...#.#.......#...#...#...##.##"
|
||||
"..#..................#.#.#....#"
|
||||
"..#.##....#........##.........."
|
||||
".....#....#....#.#.......#....."
|
||||
"##.#..##.#.....###.......#....."
|
||||
"......#...###....#..#.#...#...."
|
||||
"..............#.........#.##..."
|
||||
"#......#.............#....#...#"
|
||||
".#..#......#.###....#...#.....#"
|
||||
"..#........#.....#.....#...#..#"
|
||||
".......#...#..............#..#."
|
||||
"..#...#........#...##........#."
|
||||
".#........#....#......#......#."
|
||||
"....#..#.###.......##....#.#..#"
|
||||
"..#..###..#...................."
|
||||
"......#...#....#.........#.#..."
|
||||
"....#.##................#..#..."
|
||||
"....#......######.....#........"
|
||||
".#......##.......#....#..##.###"
|
||||
"..#...##.###..#.......#....#..."
|
||||
"....#.###...#.#.#........#....."
|
||||
"...###...#.......#..........#.#"
|
||||
"..........#...#..........##.#.."
|
||||
"..#....#........#.....#....#..#"
|
||||
"..#...#.#....##..#...##....#..."
|
||||
"........##...#..##.....#......."
|
||||
"###.......#.#...#...#.......#.#"
|
||||
"....#.#....##.###........#....."
|
||||
".....#..............#....##..##"
|
||||
"#......#.#....#.#......#.....##"
|
||||
".....#....#..#......#...#......"
|
||||
"..#.##..#.....#..#....#......#."
|
||||
".....#.#.#..........##....#...."
|
||||
".........#..#..........#.#....."
|
||||
".##..#...#......#.#..#....#...."
|
||||
"#.#..##.......#.#......##......"
|
||||
"..#.#....#.#.....#............."
|
||||
".#.........#.......#..#.#......"
|
||||
"##.........#..##.#......#......"
|
||||
"#..#.....#...#.....#.........#."
|
||||
"..........#..##..##.#..##...###"
|
||||
"..##.....#...#..##...##.#.#...."
|
||||
"..#..........#.#.....##.#....#."
|
||||
".##..#..#.........###.......#.."
|
||||
"......##....#...##....##......."
|
||||
".....#.#.##...............#...."
|
||||
"#..#......#.....#..#..#.#.....#"
|
||||
".....##.#....#.#.....#.#.#....."
|
||||
"....#..#.#..##....#.....#....#."
|
||||
"#...#.....#....#....#.#.#......"
|
||||
".....#................#.......#"
|
||||
".......#..#.#...#.#......#..#.#"
|
||||
"...........#....#....###...#.#."
|
||||
"#.##....##..###.#.#......#.##.#"
|
||||
"..##...#.#..#..#...#.....#.#.#."
|
||||
"#.....###.#..#.#...#.#......#.#"
|
||||
"..##.#...#...#.#.....#.#......."
|
||||
"#....#...#.##......#.#......#.."
|
||||
"..#.....##.....#..............."
|
||||
".....###...##.#...........#...."
|
||||
"...#..##.....##....#..........."
|
||||
".....#..#......#..........#...."
|
||||
"....##..##.#...#...#.#.....#.##"
|
||||
".#.....###..###.#...#.#..#....#"
|
||||
".#..........#...#..#.#.#..#...#"
|
||||
".##.##..#..#....#....####......"
|
||||
"....#..#.#..........#.........."
|
||||
"###...#.#..#..#...#..###......."
|
||||
"####.#...#....#..#...#..#......"
|
||||
".....##....#.#...#....##....##."
|
||||
"....#.#.##....#.##..#....#.#.#."
|
||||
"#......#..#.###....#####.##...."
|
||||
"..##..#.#.#..#........##.##..##"
|
||||
"#.#...#..#..#......#..#.....#.."
|
||||
".###.....#.#....#.#..##.....#.#"
|
||||
"....#......#.#...#...#.#....#.#"
|
||||
".....#.###.##.................."
|
||||
".#..........#........#.#...##.#"
|
||||
".##......#.#.#..#....##.###..#."
|
||||
"..#.##....#....#.........#.#..#"
|
||||
"........#..#..#.#.####.....##.."
|
||||
"#..#.##.#......#.#..##.#...#..#"
|
||||
"..#.#.##..#.##..........#......"
|
||||
"##.#.....#.#.##..#..##.....##.#"
|
||||
".##........#..#.....#...#.##.##"
|
||||
"...#....#.#.#.........##.....#."
|
||||
"...#....#.#....#...#..#........"
|
||||
".....#...#..#...#.##......##..."
|
||||
"##.........#......#..........##"
|
||||
".#......#.....##....#.#.#.....#"
|
||||
"..#.###......#..#.#....#.....#."
|
||||
".#.......#...#...#.#.#.#..##..."
|
||||
"...#..............#...###.....#"
|
||||
"...##......#.#..#.#........#.#."
|
||||
"..##.#....#..........##...#.#.."
|
||||
"..#...#.....#.######...##...#.."
|
||||
"#...#...#............#.....#..."
|
||||
".###..###.##..#.........#......"
|
||||
".#........##..#....#...#.#..##."
|
||||
"#.#.##.#.#...###..............."
|
||||
"..#.#.#......#.#.#....#.....#.#"
|
||||
".#...........#.##.#..#.###....."
|
||||
".###.#....#...........##.#.#..."
|
||||
".#...#...........#..##........."
|
||||
".#...#.#...........#..###....#."
|
||||
".##.......#.....#.....##....#.."
|
||||
"#.......#........#...##.##..#.#"
|
||||
"....#..###..#.....##.......#..."
|
||||
"......###.#...#..#....#.#...#.."
|
||||
"..#..#.......##...#.#.#...#...."
|
||||
"......#..#.......#.......##.#.."
|
||||
"#.#....###.....#...#..#...#...."
|
||||
"#...#.##.#........#..........##"
|
||||
".....#.#.##.#.#..#..##.......##"
|
||||
".#.#.......##....#.#..........."
|
||||
"#..##.............##...#.#..#.."
|
||||
"#...........#.#......#.##.##..#"
|
||||
"...#...#...........#....###.#.#"
|
||||
".##..#.#.#....#....#####......."
|
||||
"..#...#.....#.#....#..........."
|
||||
".#..#........#.....#.#......#.."
|
||||
".#.........#...#...#.#.#..#...."
|
||||
".##.##......#.#...#.......#...#"
|
||||
".##...#..#..........#...#.....#"
|
||||
"#..........#..#...#.#......#..."
|
||||
"....##......#...##..##..#....#."
|
||||
".##.......#...#.#..##..#..#...."
|
||||
".#.#................#....#....."
|
||||
"..#..#..###.......#............"
|
||||
"...##.....#..#......#....#....."
|
||||
"....#...###...#....#..##...#.#."
|
||||
"#.........#.......#...#....#..."
|
||||
".#.#...#.#....##....#.#..##.#.."
|
||||
"...#..#..#....#..#.#..##.....##"
|
||||
"..#..#.#.#....#...#....#..#...."
|
||||
"......###.....#...##.#..#.#...#"
|
||||
".#.#.#..#.##........#.#....#..."
|
||||
".#..........#....#.#.......#..."
|
||||
"#.....#........#........#....#."
|
||||
".#.#..#...#...................#"
|
||||
"....####..#..#..#..#....#..#.#."
|
||||
"..##.#..........#.##..#.....##."
|
||||
"..................##..........#"
|
||||
"....##....###.....#..#...#.#..."
|
||||
".##.........#..#..............."
|
||||
"....##..###....#.##............"
|
||||
"#.#...###.#..##...#...........#"
|
||||
".....#..#......#.....#........."
|
||||
"..#..##...#.....#.....#.#......"
|
||||
"......#....###.#..#.#.#....#..#"
|
||||
"#...#.......#.##.....#........."
|
||||
".#.#..#...#.............##....."
|
||||
"......#..............#.....#..#"
|
||||
"......#......###....#...#......"
|
||||
".....#.....#...#.......###....."
|
||||
"#..........##......##.#.#.....#"
|
||||
"....#.......#..#......#.......#"
|
||||
"..#...#.###...........#..#.###."
|
||||
".....#...#.#...........#.#...##"
|
||||
"........#.#.#........#.#.....#."
|
||||
"....##..##.#.#..#.#....#.#.##.."
|
||||
"..#.#.#......##.....#...#.#...#"
|
||||
"##...#..#......#.#.#..#...#...."
|
||||
"....#..##...........#..#..#..#."
|
||||
".#..##...#...#...##.#..#.#....#"
|
||||
".#.....####.#..#..#....##..#.#."
|
||||
".#....#..#......#.....#.#.#...."
|
||||
"....#..#.....#......#.........."
|
||||
"..#.#..###.....#...#...#.....##"
|
||||
"..#.#...##..#...........####..."
|
||||
".#.##....##.#......#.....##.#.."
|
||||
"#.##..#....#.###..........##..."
|
||||
".###...#......#.#....##........"
|
||||
"...................#..#.....#.."
|
||||
"#.#...#.#..#.....#...#..####.##"
|
||||
"....#.##..##...##.##.....#....."
|
||||
".#...#.##...........#.......##."
|
||||
"###..#.....##...#.........##..."
|
||||
".###....##...###..............."
|
||||
".#....#####........#.#.#.##...."
|
||||
".#.#....####.##........#......."
|
||||
".....#......#.................."
|
||||
"......###.....##......#..##.#.."
|
||||
"....#.#...........##.#....##.#."
|
||||
"...................#.#.#......."
|
||||
"#.#.#........#..#.......##....."
|
||||
"..#...#...#....#......#....##.#"
|
||||
"#..#..............#......#....#"
|
||||
"......#.........##............."
|
||||
".....#.#....##..#.......#......"
|
||||
"......#.......#...........#...."
|
||||
"....#....#.#..##.#....#...#...."
|
||||
"#.#.#..#..#.#.#.#...#....#....#"
|
||||
".#.#....#...#.#..#......#.....#"
|
||||
".#...........#.#....##.....#..."
|
||||
"........#...#....#....##.....##"
|
||||
"#..#..........#..#..#.....#...."
|
||||
"#.#.###..........#.##....#...##"
|
||||
"..#................#.##.##....."
|
||||
"..#...#.##...##...#.........#.."
|
||||
"#....#......#......#.........#."
|
||||
"##...#...##.#.........#......#."
|
||||
".......#.....#................."
|
||||
"...#...#.....##.........#.#..#."
|
||||
"..#......#...#.......#......#.#"
|
||||
"#.......#...#.##.#..##..#......"
|
||||
".#.#............#...###..#....."
|
||||
"...#.......##.......#....#..#.."
|
||||
".....#..#.#....#.#............."
|
||||
"#....#...##.##....#....##......"
|
||||
"........#......#.......#....#.."
|
||||
"..#..#..##......##.#..#.#..##.."
|
||||
"....##......#.##.##......#....."
|
||||
"........##.#...#.....#.......#."
|
||||
"..##.#....#..#......#.##......."
|
||||
"..##.####.#...#.#....#........."
|
||||
".#........#.....#..#....#...#.#"
|
||||
"###....##......#..#..#.##..#..."
|
||||
"..........###.#..#..#....#....."
|
||||
"..#.........#....#.....#....#.#"
|
||||
".#...#.#.....##.#...#...#.#..#."
|
||||
"....##......##.##.#.....#..#..."
|
||||
"....#.##...##.......#..##......"
|
||||
"#..........#..#....#.......#.#."
|
||||
"..#.....#.................#...."
|
||||
"..........#.#.#.....#.#....#..#"
|
||||
".......#..........#.##....#...."
|
||||
"#..#.....#.......#........#...."
|
||||
"#.....##..#.........##..#..#.#."
|
||||
".##.#...#..........#....#......"
|
||||
"....#..#.#......#.##..#..#.##.."
|
||||
"...##.####....#.....#.#...##..."
|
||||
"..#.#....#.#........#.........."
|
||||
"#...#.#.##.##....##..#...#...#."
|
||||
"...#.#.......#..#...#..#..##..#"
|
||||
".....#....#........###.....#..."
|
||||
".......#..#.##....#.#.....#...."
|
||||
"....##....#....#.......#.....#."
|
||||
".........#........###...##....."
|
||||
"#.#..#...##.........#.#..#....#"
|
||||
"...##...........#.........#...#"
|
||||
"......#.#.#.........#..#.#.#..."
|
||||
"........##.###....#..#.......#."
|
||||
"....#.#...#......#..#........##"
|
||||
".#....##....#...#.##.........#."
|
||||
"####.#..#...........##.#.#....."
|
||||
"...#....#..#.....#..##.####.#.."
|
||||
".##...#...........#.#.........#"
|
||||
"#.#..#..#...#.#.#.........#..#."
|
||||
"#......###............#...#...."
|
||||
"..#.......#....#...#...#..#...#"
|
||||
"#.#.#...##..#...#...#.......##."
|
||||
"......#.#.......#..........#.#."
|
||||
"...............#...#..#...#.#.."
|
||||
".#.#...##.####..##.##....#..##."
|
||||
"#..####.......##.#........#...#"
|
||||
"......###....##...#.#..#.##...."
|
||||
".##.....###..#...#.###.###....."
|
||||
"..#...#.....#...#..#..##..#...."
|
||||
"...#...##.....##........#.#.##."
|
||||
".#...#..#....#....#..###....#.#"
|
||||
"..#.#.#.#.#..........#.#..#..##"
|
||||
".......###....................."
|
||||
"##.#......#.##.....#.........#."
|
||||
"......................#.#.....#"
|
||||
"#..#........##.......#..##..#.#"
|
||||
"#.#.#.....##.#.##.##.#....##..."
|
||||
".#...#.....#.........#.....#..."
|
||||
"..#.........#.##.#.###.#......#"
|
||||
".........#..#.##...#.......###."
|
||||
".....##........#......#........"
|
||||
"...#.#...##...#........#.##...."
|
||||
".........##............#.####.."
|
||||
"#....#...#...#..#....#..#.#.#.#"
|
||||
"..#.........#......#.##........"
|
||||
"....#.....#........#........#.#"
|
||||
".##.#..#.#..#..###......###...."
|
||||
"#.###.....#.#.#.##........#..##"
|
||||
"#.#..#...##.....#....#...#.#..."
|
||||
"......#....#.....#...#........."
|
||||
"...#........##.......#.##..####"
|
||||
"..#..#....#....#..#..#...#.##.."
|
||||
".##.....#............#...#....."
|
||||
"......#.......#.....#...#.#.#.."
|
||||
".........#.....#...##.........."
|
||||
".....#........##...........#..."
|
||||
"#.#..##.#...#....#....#........"
|
||||
"#.##..#.#.......#...#......#..."
|
||||
"...........#.#..#..#.....##.#.."
|
||||
"#....#.##.......#......#.##..#."
|
||||
".....#........#.##.#...#.....#."
|
||||
".....###..#.......##..........."
|
||||
".........#.#.#.....#.##.......#"
|
||||
".......#....#......#.#.....#..."
|
||||
"##........#...#..#.#.........#."
|
||||
"##...........#.##...##......#.."
|
||||
"..#.###.#.#.#...####..#....###."
|
||||
".........#...#.....##....#.#.##"
|
||||
".###..###.#.#.....#.##........."
|
||||
"#..#...#.#.................##.#"
|
||||
"##.........#.#....#.#...#.###.."
|
||||
"#.#....#..............#.##.#..."
|
||||
"...#..#....##.#..#.......#..##."
|
||||
".#..#.###......##..........#..#"
|
||||
".##....#.#....#....#.#..#......"
|
||||
".......#.....#..#....#.##...#.."
|
||||
"#.#.#.........###..#..#.....#.."
|
||||
"...##..##...##....#..#......#.."
|
||||
"..........#....#..........#...."
|
||||
"#..##..#...#......#.....#.#...."
|
||||
"#..##..#....#.#.#...#.........."
|
||||
"......##..#.........#........#."
|
||||
".##..#..#......###.....#..#...."
|
||||
".....#..#.##..........#.#..#..."
|
||||
;
|
1177
src/test/kc/adventofcode/2020-04.c
Normal file
1177
src/test/kc/adventofcode/2020-04.c
Normal file
File diff suppressed because it is too large
Load Diff
4
src/test/kc/adventofcode/README.txt
Normal file
4
src/test/kc/adventofcode/README.txt
Normal 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
|
66
src/test/kc/adventofcode/longlong.c
Normal file
66
src/test/kc/adventofcode/longlong.c
Normal 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Tests the target platform ASM6502
|
||||
|
||||
#pragma target(asm6502)
|
||||
#pragma start_address(0x2000)
|
||||
#pragma start_address(0x3000)
|
||||
|
||||
unsigned char TABLE[10];
|
||||
|
||||
|
26
src/test/kc/struct-unwinding-1.c
Normal file
26
src/test/kc/struct-unwinding-1.c
Normal 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;
|
||||
}
|
37
src/test/kc/struct-unwinding-2.c
Normal file
37
src/test/kc/struct-unwinding-2.c
Normal 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;
|
||||
}
|
39
src/test/kc/struct-unwinding-3.c
Normal file
39
src/test/kc/struct-unwinding-3.c
Normal 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
13
src/test/kc/varcall-1.c
Normal 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
17
src/test/kc/varcall-2.c
Normal 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
17
src/test/kc/varcall-3.c
Normal 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
22
src/test/kc/varcall-4.c
Normal 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 };
|
||||
}
|
1501
src/test/ref/adventofcode/2020-01.asm
Normal file
1501
src/test/ref/adventofcode/2020-01.asm
Normal file
File diff suppressed because it is too large
Load Diff
674
src/test/ref/adventofcode/2020-01.cfg
Normal file
674
src/test/ref/adventofcode/2020-01.cfg
Normal 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
|
11884
src/test/ref/adventofcode/2020-01.log
Normal file
11884
src/test/ref/adventofcode/2020-01.log
Normal file
File diff suppressed because one or more lines are too long
354
src/test/ref/adventofcode/2020-01.sym
Normal file
354
src/test/ref/adventofcode/2020-01.sym
Normal 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 ]
|
918
src/test/ref/adventofcode/2020-02.asm
Normal file
918
src/test/ref/adventofcode/2020-02.asm
Normal file
File diff suppressed because one or more lines are too long
507
src/test/ref/adventofcode/2020-02.cfg
Normal file
507
src/test/ref/adventofcode/2020-02.cfg
Normal 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
|
8455
src/test/ref/adventofcode/2020-02.log
Normal file
8455
src/test/ref/adventofcode/2020-02.log
Normal file
File diff suppressed because one or more lines are too long
271
src/test/ref/adventofcode/2020-02.sym
Normal file
271
src/test/ref/adventofcode/2020-02.sym
Normal file
File diff suppressed because one or more lines are too long
835
src/test/ref/adventofcode/2020-03.asm
Normal file
835
src/test/ref/adventofcode/2020-03.asm
Normal file
File diff suppressed because one or more lines are too long
464
src/test/ref/adventofcode/2020-03.cfg
Normal file
464
src/test/ref/adventofcode/2020-03.cfg
Normal 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
|
7640
src/test/ref/adventofcode/2020-03.log
Normal file
7640
src/test/ref/adventofcode/2020-03.log
Normal file
File diff suppressed because one or more lines are too long
244
src/test/ref/adventofcode/2020-03.sym
Normal file
244
src/test/ref/adventofcode/2020-03.sym
Normal file
File diff suppressed because one or more lines are too long
845
src/test/ref/adventofcode/2020-04.asm
Normal file
845
src/test/ref/adventofcode/2020-04.asm
Normal file
File diff suppressed because one or more lines are too long
441
src/test/ref/adventofcode/2020-04.cfg
Normal file
441
src/test/ref/adventofcode/2020-04.cfg
Normal 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
|
9638
src/test/ref/adventofcode/2020-04.log
Normal file
9638
src/test/ref/adventofcode/2020-04.log
Normal file
File diff suppressed because one or more lines are too long
1340
src/test/ref/adventofcode/2020-04.sym
Normal file
1340
src/test/ref/adventofcode/2020-04.sym
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Tests the target platform ASM6502
|
||||
.pc = $2000 "Program"
|
||||
.pc = $3000 "Program"
|
||||
main: {
|
||||
ldx #0
|
||||
__b1:
|
||||
|
@ -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: {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
58
src/test/ref/struct-unwinding-1.asm
Normal file
58
src/test/ref/struct-unwinding-1.asm
Normal 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
|
20
src/test/ref/struct-unwinding-1.cfg
Normal file
20
src/test/ref/struct-unwinding-1.cfg
Normal 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
|
423
src/test/ref/struct-unwinding-1.log
Normal file
423
src/test/ref/struct-unwinding-1.log
Normal 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
|
||||
|
14
src/test/ref/struct-unwinding-1.sym
Normal file
14
src/test/ref/struct-unwinding-1.sym
Normal 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 ]
|
86
src/test/ref/struct-unwinding-2.asm
Normal file
86
src/test/ref/struct-unwinding-2.asm
Normal 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
|
47
src/test/ref/struct-unwinding-2.cfg
Normal file
47
src/test/ref/struct-unwinding-2.cfg
Normal 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
|
660
src/test/ref/struct-unwinding-2.log
Normal file
660
src/test/ref/struct-unwinding-2.log
Normal 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
|
||||
|
34
src/test/ref/struct-unwinding-2.sym
Normal file
34
src/test/ref/struct-unwinding-2.sym
Normal 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 ]
|
27
src/test/ref/varcall-1.asm
Normal file
27
src/test/ref/varcall-1.asm
Normal 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
|
||||
}
|
19
src/test/ref/varcall-1.cfg
Normal file
19
src/test/ref/varcall-1.cfg
Normal 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
221
src/test/ref/varcall-1.log
Normal 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
|
||||
|
6
src/test/ref/varcall-1.sym
Normal file
6
src/test/ref/varcall-1.sym
Normal 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 ]
|
43
src/test/ref/varcall-2.asm
Normal file
43
src/test/ref/varcall-2.asm
Normal 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
|
||||
}
|
27
src/test/ref/varcall-2.cfg
Normal file
27
src/test/ref/varcall-2.cfg
Normal 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
354
src/test/ref/varcall-2.log
Normal 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
Loading…
Reference in New Issue
Block a user