mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-24 01:30:50 +00:00
Added a bunch of complex struct copying tests.
This commit is contained in:
parent
9db24ceb01
commit
1fffef91f5
@ -0,0 +1,8 @@
|
||||
ldy #0
|
||||
!:
|
||||
lda {c2},x
|
||||
sta {c1},y
|
||||
inx
|
||||
iny
|
||||
cpy #{c3}
|
||||
bne !-
|
@ -0,0 +1,8 @@
|
||||
ldx #0
|
||||
!:
|
||||
lda {c2},y
|
||||
sta {c1},x
|
||||
iny
|
||||
inx
|
||||
cpx #{c3}
|
||||
bne !-
|
@ -0,0 +1,4 @@
|
||||
lda {c2},x
|
||||
sta {c1}
|
||||
lda {c2}+1,x
|
||||
sta {c1}+1
|
@ -0,0 +1,4 @@
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
lda {c2}+1,y
|
||||
sta {c1}+1
|
@ -0,0 +1,4 @@
|
||||
lda {c2}
|
||||
sta {c1},x
|
||||
lda {c2}+1
|
||||
sta {c1}+1,x
|
@ -0,0 +1,4 @@
|
||||
lda {c2}
|
||||
sta {c1},y
|
||||
lda {c2}+1
|
||||
sta {c1}+1,y
|
@ -4,10 +4,7 @@ import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||
import dk.camelot64.kickc.model.values.ConstantString;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
/** Unary Cast to double word operator ( (dword) x ) */
|
||||
public class OperatorCastDWord extends OperatorCast {
|
||||
@ -20,6 +17,8 @@ public class OperatorCastDWord extends OperatorCast {
|
||||
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
|
||||
if(value instanceof ConstantInteger) {
|
||||
return new ConstantInteger(0xffffffffL & ((ConstantInteger) value).getValue(), SymbolType.DWORD);
|
||||
} else if(value instanceof ConstantChar) {
|
||||
return new ConstantInteger(((ConstantChar) value).getInteger(), SymbolType.DWORD);
|
||||
} else if(value instanceof ConstantPointer) {
|
||||
return new ConstantInteger(0xffff & ((ConstantPointer) value).getLocation(), SymbolType.DWORD);
|
||||
} else if(value instanceof ConstantString) {
|
||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.model.operators;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantChar;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
|
||||
@ -17,6 +18,8 @@ public class OperatorCastSByte extends OperatorCast {
|
||||
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
|
||||
if(value instanceof ConstantInteger) {
|
||||
return new ConstantInteger(0xff & ((ConstantInteger) value).getValue(), SymbolType.SBYTE);
|
||||
} else if(value instanceof ConstantChar) {
|
||||
return new ConstantInteger(((ConstantChar) value).getInteger(), SymbolType.SBYTE);
|
||||
}
|
||||
throw new CompileError("Calculation not implemented " + getOperator() + " " + value );
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.model.operators;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantChar;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
|
||||
@ -17,6 +18,8 @@ public class OperatorCastSDWord extends OperatorCast {
|
||||
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
|
||||
if(value instanceof ConstantInteger) {
|
||||
return new ConstantInteger(0xffffffffL & ((ConstantInteger) value).getValue(), SymbolType.SDWORD);
|
||||
} else if(value instanceof ConstantChar) {
|
||||
return new ConstantInteger(((ConstantChar) value).getInteger(), SymbolType.SDWORD);
|
||||
}
|
||||
throw new CompileError("Calculation not implemented " + getOperator() + " " + value );
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.model.operators;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantChar;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
|
||||
@ -17,6 +18,8 @@ public class OperatorCastSWord extends OperatorCast {
|
||||
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
|
||||
if(value instanceof ConstantInteger) {
|
||||
return new ConstantInteger(0xffff & ((ConstantInteger) value).getValue(), SymbolType.SWORD);
|
||||
} else if(value instanceof ConstantChar) {
|
||||
return new ConstantInteger(((ConstantChar) value).getInteger(), SymbolType.SWORD);
|
||||
}
|
||||
throw new CompileError("Calculation not implemented " + getOperator() + " " + value );
|
||||
}
|
||||
|
@ -4,10 +4,7 @@ import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||
import dk.camelot64.kickc.model.values.ConstantString;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
/** Unary Cast to word operator ( (word) x ) */
|
||||
public class OperatorCastWord extends OperatorCast {
|
||||
@ -20,6 +17,8 @@ public class OperatorCastWord extends OperatorCast {
|
||||
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
|
||||
if(value instanceof ConstantInteger) {
|
||||
return new ConstantInteger(0xffff & ((ConstantInteger) value).getValue(), SymbolType.WORD);
|
||||
} else if(value instanceof ConstantChar) {
|
||||
return new ConstantInteger(((ConstantChar) value).getInteger(), SymbolType.WORD);
|
||||
} else if(value instanceof ConstantPointer) {
|
||||
return new ConstantInteger(0xffff & ((ConstantPointer) value).getLocation(), SymbolType.WORD);
|
||||
} else if(value instanceof ConstantString) {
|
||||
|
@ -4,10 +4,7 @@ import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
@ -314,6 +311,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
if(value instanceof ConstantStructValue)
|
||||
// A constant struct value
|
||||
return true;
|
||||
if(value instanceof StructMemberRef && ((StructMemberRef) value).getStruct() instanceof PointerDereference)
|
||||
// A member of a struct in memory
|
||||
return true;
|
||||
if(value instanceof PointerDereference) {
|
||||
final SymbolType symbolType = SymbolTypeInference.inferType(getProgram().getScope(), value);
|
||||
if(symbolType instanceof SymbolTypeStruct)
|
||||
@ -341,15 +341,28 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
return new RValueUnwindingStructVariable(variable);
|
||||
}
|
||||
}
|
||||
if(value instanceof StructZero) {
|
||||
if(value instanceof StructZero)
|
||||
return new RValueUnwindingZero(valueType, null);
|
||||
}
|
||||
if(value instanceof ConstantStructValue) {
|
||||
if(value instanceof ConstantStructValue)
|
||||
return new RValueUnwindingConstant(valueType, null, (ConstantStructValue) value);
|
||||
}
|
||||
if(value instanceof PointerDereference) {
|
||||
if(value instanceof PointerDereference)
|
||||
return new RValueUnwindingStructPointerDeref((PointerDereference) value, (SymbolTypeStruct) valueType);
|
||||
if(value instanceof StructMemberRef && ((StructMemberRef) value).getStruct() instanceof PointerDereferenceIndexed) {
|
||||
final StructMemberRef structMemberRef = (StructMemberRef) value;
|
||||
final PointerDereferenceIndexed structPointerDerefIdx = (PointerDereferenceIndexed) structMemberRef.getStruct();
|
||||
final SymbolType structPointerType = SymbolTypeInference.inferType(getScope(), structPointerDerefIdx);
|
||||
if(!(structPointerType instanceof SymbolTypeStruct))
|
||||
throw new CompileError("Value is not a struct"+structPointerDerefIdx.toString(getProgram()), currentStmt);
|
||||
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) structPointerType).getStructDefinition(getScope());
|
||||
final String memberName = structMemberRef.getMemberName();
|
||||
final Variable member = structDefinition.getMember(memberName);
|
||||
final SymbolType memberType = member.getType();
|
||||
final ArraySpec memberArraySpec = member.getArraySpec();
|
||||
final ConstantRef memberOffsetConstant = PassNStructPointerRewriting.getMemberOffsetConstant(getScope(), structDefinition, memberName);
|
||||
return new RValueUnwindingStructPointerDereferenceIndexedMember(structPointerDerefIdx, memberType, memberArraySpec, memberOffsetConstant, currentBlock, stmtIt, currentStmt);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -396,6 +409,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
return new StructUnwindingPointerDerefSimple((PointerDereferenceSimple) value, structDefinition, stmtIt, currentBlock, currentStmt);
|
||||
} else if(value instanceof PointerDereferenceIndexed) {
|
||||
return new StructUnwindingPointerDerefIndexed((PointerDereferenceIndexed) value, structDefinition, stmtIt, currentBlock, currentStmt);
|
||||
} else if(value instanceof StructMemberRef && ((StructMemberRef) value).getStruct() instanceof PointerDereferenceIndexed) {
|
||||
final StructMemberRef structMemberRef = (StructMemberRef) value;
|
||||
return new StructUnwindingMemberOfPointerDerefIndexed((PointerDereferenceIndexed) structMemberRef.getStruct(),structMemberRef.getMemberName(), structDefinition, stmtIt, currentBlock, currentStmt);
|
||||
} else if(value instanceof ConstantStructValue) {
|
||||
return new StructUnwindingConstant((ConstantStructValue) value, structDefinition);
|
||||
} else if(value instanceof StructZero) {
|
||||
|
@ -11,7 +11,7 @@ import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
public class RValueUnwindingStructPointerDerefSimple implements RValueUnwinding {
|
||||
public class RValueUnwindingStructPointerDerefSimpleMember implements RValueUnwinding {
|
||||
private final PointerDereferenceSimple structPointerDeref;
|
||||
private final ArraySpec memberArraySpec;
|
||||
private final SymbolType memberType;
|
||||
@ -21,7 +21,7 @@ public class RValueUnwindingStructPointerDerefSimple implements RValueUnwinding
|
||||
private final ListIterator<Statement> stmtIt;
|
||||
private final Statement currentStmt;
|
||||
|
||||
public RValueUnwindingStructPointerDerefSimple(PointerDereferenceSimple structPointerDeref, ArraySpec memberArraySpec, SymbolType memberType, ConstantRef memberOffsetConstant, ControlFlowBlock currentBlock, ListIterator<Statement> stmtIt, Statement currentStmt) {
|
||||
public RValueUnwindingStructPointerDerefSimpleMember(PointerDereferenceSimple structPointerDeref, ArraySpec memberArraySpec, SymbolType memberType, ConstantRef memberOffsetConstant, ControlFlowBlock currentBlock, ListIterator<Statement> stmtIt, Statement currentStmt) {
|
||||
this.structPointerDeref = structPointerDeref;
|
||||
this.memberArraySpec = memberArraySpec;
|
||||
this.memberType = memberType;
|
@ -7,11 +7,12 @@ import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
class RValueUnwindingStructPointerDereferenceIndexedMember implements RValueUnwinding {
|
||||
public class RValueUnwindingStructPointerDereferenceIndexedMember implements RValueUnwinding {
|
||||
private final PointerDereferenceIndexed structPointerDeref;
|
||||
private final SymbolType memberType;
|
||||
private final ArraySpec memberArraySpec;
|
||||
@ -54,7 +55,7 @@ class RValueUnwindingStructPointerDereferenceIndexedMember implements RValueUnwi
|
||||
|
||||
@Override
|
||||
public boolean isBulkCopyable() {
|
||||
return getArraySpec() != null;
|
||||
return getArraySpec() != null || memberType instanceof SymbolTypeStruct;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,6 +65,6 @@ class RValueUnwindingStructPointerDereferenceIndexedMember implements RValueUnwi
|
||||
|
||||
@Override
|
||||
public RValue getBulkRValue(ProgramScope scope) {
|
||||
throw new RuntimeException("TODO: Implement!");
|
||||
return getUnwinding(scope);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
package dk.camelot64.kickc.passes.unwinding;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.CastValue;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.PointerDereferenceIndexed;
|
||||
import dk.camelot64.kickc.passes.PassNStructPointerRewriting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public class StructUnwindingMemberOfPointerDerefIndexed implements StructUnwinding {
|
||||
|
||||
// The struct member reference a[i].b
|
||||
private final PointerDereferenceIndexed structRef;
|
||||
private final String memberRef;
|
||||
|
||||
// The referenced struct (type of b)
|
||||
private final StructDefinition structDefinition;
|
||||
|
||||
// For adding any needed statements
|
||||
private final ListIterator<Statement> stmtIt;
|
||||
private final ControlFlowBlock currentBlock;
|
||||
private final Statement currentStmt;
|
||||
|
||||
public StructUnwindingMemberOfPointerDerefIndexed(PointerDereferenceIndexed structRef, String memberRef, StructDefinition structDefinition, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, Statement currentStmt) {
|
||||
this.structRef = structRef;
|
||||
this.memberRef = memberRef;
|
||||
this.structDefinition = structDefinition;
|
||||
this.stmtIt = stmtIt;
|
||||
this.currentBlock = currentBlock;
|
||||
this.currentStmt = currentStmt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMemberNames() {
|
||||
Collection<Variable> structMemberVars = structDefinition.getAllVariables(false);
|
||||
ArrayList<String> memberNames = new ArrayList<>();
|
||||
for(Variable structMemberVar : structMemberVars) {
|
||||
memberNames.add(structMemberVar.getLocalName());
|
||||
}
|
||||
return memberNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValueUnwinding getMemberUnwinding(String memberName, ProgramScope programScope) {
|
||||
// a[i].b.c -> ((memberType*)a+OFFSET_B+OFFSET_C)[i]
|
||||
|
||||
|
||||
// Type of b
|
||||
SymbolType outerStructType = SymbolTypeInference.inferType(programScope, structRef);
|
||||
if(!(outerStructType instanceof SymbolTypeStruct))
|
||||
throw new CompileError("Error! Member is not a struct " + memberRef, currentStmt);
|
||||
StructDefinition outerStructDefinition = ((SymbolTypeStruct) outerStructType).getStructDefinition(programScope);
|
||||
ConstantRef outerMemberOffsetConstant = PassNStructPointerRewriting.getMemberOffsetConstant(programScope, outerStructDefinition, memberRef);
|
||||
|
||||
Variable member = this.structDefinition.getMember(memberName);
|
||||
SymbolType memberType = member.getType();
|
||||
|
||||
Scope scope = programScope.getScope(currentBlock.getScope());
|
||||
Variable outerMemberAddress = scope.addVariableIntermediate();
|
||||
outerMemberAddress.setType(new SymbolTypePointer(memberType));
|
||||
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(memberType), structRef.getPointer());
|
||||
// Add statement $1 = (elmType*)ptr_struct + OFFSET_B
|
||||
stmtIt.add(new StatementAssignment((LValue) outerMemberAddress.getRef(), structTypedPointer, Operators.PLUS, outerMemberOffsetConstant, true, currentStmt.getSource(), currentStmt.getComments()));
|
||||
// Unwind to ((elmType*)ptr_struct+OFFSET_B)[idx]
|
||||
PointerDereferenceIndexed outerMemberIndexing = new PointerDereferenceIndexed(outerMemberAddress.getRef(), structRef.getIndex());
|
||||
|
||||
ConstantRef memberOffsetConstant = PassNStructPointerRewriting.getMemberOffsetConstant(programScope, this.structDefinition, memberName);
|
||||
ArraySpec memberArraySpec = member.getArraySpec();
|
||||
|
||||
return new RValueUnwindingStructPointerDereferenceIndexedMember(outerMemberIndexing, memberType, memberArraySpec, memberOffsetConstant, currentBlock, stmtIt, currentStmt);
|
||||
}
|
||||
|
||||
}
|
@ -45,7 +45,7 @@ public class StructUnwindingPointerDerefSimple implements StructUnwinding {
|
||||
Variable member = structDefinition.getMember(memberName);
|
||||
SymbolType memberType = member.getType();
|
||||
ArraySpec memberArraySpec = member.getArraySpec();
|
||||
return new RValueUnwindingStructPointerDerefSimple(pointerDeref, memberArraySpec, memberType, memberOffsetConstant, currentBlock, stmtIt, currentStmt);
|
||||
return new RValueUnwindingStructPointerDerefSimpleMember(pointerDeref, memberArraySpec, memberType, memberOffsetConstant, currentBlock, stmtIt, currentStmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1153,6 +1153,21 @@ public class TestPrograms {
|
||||
assertError("struct-err-0", "Unknown struct type");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStruct39() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-39");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStruct38() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-38");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStruct37() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-37");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStruct36() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-36");
|
||||
|
@ -69,11 +69,11 @@ void main() {
|
||||
void show_letter(char angle) {
|
||||
struct SplineVector16 current = {0,0};
|
||||
for( byte i: 0..21) {
|
||||
struct SplineVector16 to = { letter_c[i].to.x, letter_c[i].to.y };
|
||||
struct SplineVector16 to = letter_c[i].to;
|
||||
to = { to.x - 50, to.y - 150};
|
||||
to = rotate(to, angle);
|
||||
to = { to.x + 100, to.y + 100};
|
||||
struct SplineVector16 via = { letter_c[i].via.x, letter_c[i].via.y };
|
||||
struct SplineVector16 via = letter_c[i].via;
|
||||
via = { via.x - 50, via.y - 150};
|
||||
via = rotate(via, angle);
|
||||
via = { via.x + 100, via.y + 100};
|
||||
|
32
src/test/kc/struct-37.kc
Normal file
32
src/test/kc/struct-37.kc
Normal file
@ -0,0 +1,32 @@
|
||||
// Complex C-struct - copying a sub-struct from C-standard layout to Unwound layout
|
||||
|
||||
// Vector with 16-coordinates that is part of a spline
|
||||
struct SplineVector16 {
|
||||
char x;
|
||||
char y;
|
||||
};
|
||||
|
||||
// A segment of a spline
|
||||
struct Segment {
|
||||
enum SegmentType { MOVE_TO, SPLINE_TO, LINE_TO} type;
|
||||
struct SplineVector16 to;
|
||||
struct SplineVector16 via;
|
||||
};
|
||||
|
||||
// True type letter c
|
||||
struct Segment[] letter_c = {
|
||||
{ MOVE_TO, {'a','b'}, {0,0} },
|
||||
{ SPLINE_TO, {'c','d'}, {103,169} },
|
||||
{ SPLINE_TO, {'e','f'}, {75,195} }
|
||||
};
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
char j=0;
|
||||
for( byte i: 0..2) {
|
||||
struct SplineVector16 to = letter_c[i].to;
|
||||
SCREEN[j++] = to.x;
|
||||
SCREEN[j++] = to.y;
|
||||
}
|
||||
}
|
32
src/test/kc/struct-38.kc
Normal file
32
src/test/kc/struct-38.kc
Normal file
@ -0,0 +1,32 @@
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to Unwound layout
|
||||
|
||||
// Vector with 16-coordinates that is part of a spline
|
||||
struct SplineVector16 {
|
||||
signed int x;
|
||||
signed int y;
|
||||
};
|
||||
|
||||
// A segment of a spline
|
||||
struct Segment {
|
||||
enum SegmentType { MOVE_TO, SPLINE_TO, LINE_TO} type;
|
||||
struct SplineVector16 to;
|
||||
struct SplineVector16 via;
|
||||
};
|
||||
|
||||
// True type letter c
|
||||
struct Segment[] letter_c = {
|
||||
{ MOVE_TO, {'a','b'}, {0,0} },
|
||||
{ SPLINE_TO, {'c','d'}, {103,169} },
|
||||
{ SPLINE_TO, {'e','f'}, {75,195} }
|
||||
};
|
||||
|
||||
const signed int* SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
char j=0;
|
||||
for( byte i: 0..2) {
|
||||
struct SplineVector16 to = letter_c[i].to;
|
||||
SCREEN[j++] = to.x;
|
||||
SCREEN[j++] = to.y;
|
||||
}
|
||||
}
|
32
src/test/kc/struct-39.kc
Normal file
32
src/test/kc/struct-39.kc
Normal file
@ -0,0 +1,32 @@
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to C-standard layout (expecting a memcpy)
|
||||
|
||||
// Vector with 16-coordinates that is part of a spline
|
||||
struct Vector {
|
||||
signed int x;
|
||||
signed int y;
|
||||
};
|
||||
|
||||
// A segment of a spline
|
||||
struct Segment {
|
||||
enum SegmentType { MOVE_TO, SPLINE_TO, LINE_TO} type;
|
||||
struct Vector to;
|
||||
struct Vector via;
|
||||
};
|
||||
|
||||
// True type letter c
|
||||
struct Segment[] letter_c = {
|
||||
{ MOVE_TO, {'a','b'}, {0,0} },
|
||||
{ SPLINE_TO, {'c','d'}, {103,169} },
|
||||
{ SPLINE_TO, {'e','f'}, {75,195} }
|
||||
};
|
||||
|
||||
const signed int* SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
char j=0;
|
||||
for( byte i: 0..2) {
|
||||
__ma struct Vector to = letter_c[i].to;
|
||||
SCREEN[j++] = to.x;
|
||||
SCREEN[j++] = to.y;
|
||||
}
|
||||
}
|
@ -73,8 +73,8 @@ show_letter::@1: scope:[show_letter] from show_letter show_letter::@9
|
||||
[28] (byte) show_letter::i#10 ← phi( show_letter/(byte) 0 show_letter::@9/(byte) show_letter::i#1 )
|
||||
[29] (byte~) show_letter::$32 ← (byte) show_letter::i#10 << (byte) 3
|
||||
[30] (byte~) show_letter::$20 ← (byte~) show_letter::$32 + (byte) show_letter::i#10
|
||||
[31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20)
|
||||
[32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20)
|
||||
[31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20)
|
||||
[32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20)
|
||||
[33] (signed word) show_letter::to_x#1 ← (signed word) show_letter::to_x#0 - (signed byte) $32
|
||||
[34] (signed word) show_letter::to_y#1 ← (signed word) show_letter::to_y#0 - (signed word) $96
|
||||
[35] (signed word) rotate::vector_x#0 ← (signed word) show_letter::to_x#1
|
||||
@ -91,8 +91,8 @@ show_letter::@6: scope:[show_letter] from show_letter::@1
|
||||
[44] (signed word) show_letter::current_y#10 ← (signed word) show_letter::to_y#2 + (signed byte) $64
|
||||
[45] (byte~) show_letter::$34 ← (byte) show_letter::i#10 << (byte) 3
|
||||
[46] (byte~) show_letter::$21 ← (byte~) show_letter::$34 + (byte) show_letter::i#10
|
||||
[47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21)
|
||||
[48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21)
|
||||
[47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21)
|
||||
[48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21)
|
||||
[49] (signed word) show_letter::via_x#1 ← (signed word) show_letter::via_x#0 - (signed byte) $32
|
||||
[50] (signed word) show_letter::via_y#1 ← (signed word) show_letter::via_y#0 - (signed word) $96
|
||||
[51] (signed word) rotate::vector_x#1 ← (signed word) show_letter::via_x#1
|
||||
|
@ -12,8 +12,6 @@ Fixing pointer array-indexing *((dword*) ultoa::digit_values + (byte) ultoa::dig
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) show_letter::i)
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) show_letter::i)
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) show_letter::i)
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) show_letter::i)
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) show_letter::i)
|
||||
Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (number) 0)
|
||||
Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (byte) bitmap_plot_spline_8seg::n)
|
||||
Fixing pointer array-indexing *((const struct SplineVector16*) SPLINE_8SEG + (byte) bitmap_plot_spline_8seg::n)
|
||||
@ -203,8 +201,8 @@ Adding struct value member variable copy *((signed word*~) spline_8segB::$35 + (
|
||||
Adding struct value member variable copy *((signed word*~) spline_8segB::$36 + (number~) spline_8segB::$32) ← (signed word)(number~) spline_8segB::$21
|
||||
Adding struct value member variable copy (signed word) show_letter::current_x ← (signed word) 0
|
||||
Adding struct value member variable copy (signed word) show_letter::current_y ← (signed word) 0
|
||||
Adding struct value member variable copy (signed word) show_letter::to_x ← *((const struct Segment*) letter_c + (byte~) show_letter::$20).to.x
|
||||
Adding struct value member variable copy (signed word) show_letter::to_y ← *((const struct Segment*) letter_c + (byte~) show_letter::$20).to.y
|
||||
Adding struct value member variable copy (signed word) show_letter::to_x ← *((signed word*~) show_letter::$24 + (byte~) show_letter::$20)
|
||||
Adding struct value member variable copy (signed word) show_letter::to_y ← *((signed word*~) show_letter::$26 + (byte~) show_letter::$20)
|
||||
Adding struct value member variable copy (signed word) show_letter::to_x ← (signed word)(number~) show_letter::$0
|
||||
Adding struct value member variable copy (signed word) show_letter::to_y ← (signed word)(number~) show_letter::$1
|
||||
Converted procedure call LValue to member unwinding { (signed word~) show_letter::$2_x, (signed word~) show_letter::$2_y } ← call rotate (struct SplineVector16) show_letter::to (byte) show_letter::angle
|
||||
@ -213,8 +211,8 @@ Adding struct value member variable copy (signed word) show_letter::to_x ← (si
|
||||
Adding struct value member variable copy (signed word) show_letter::to_y ← (signed word~) show_letter::$2_y
|
||||
Adding struct value member variable copy (signed word) show_letter::to_x ← (signed word)(number~) show_letter::$3
|
||||
Adding struct value member variable copy (signed word) show_letter::to_y ← (signed word)(number~) show_letter::$4
|
||||
Adding struct value member variable copy (signed word) show_letter::via_x ← *((const struct Segment*) letter_c + (byte~) show_letter::$21).via.x
|
||||
Adding struct value member variable copy (signed word) show_letter::via_y ← *((const struct Segment*) letter_c + (byte~) show_letter::$21).via.y
|
||||
Adding struct value member variable copy (signed word) show_letter::via_x ← *((signed word*~) show_letter::$28 + (byte~) show_letter::$21)
|
||||
Adding struct value member variable copy (signed word) show_letter::via_y ← *((signed word*~) show_letter::$30 + (byte~) show_letter::$21)
|
||||
Adding struct value member variable copy (signed word) show_letter::via_x ← (signed word)(number~) show_letter::$5
|
||||
Adding struct value member variable copy (signed word) show_letter::via_y ← (signed word)(number~) show_letter::$6
|
||||
Converted procedure call LValue to member unwinding { (signed word~) show_letter::$7_x, (signed word~) show_letter::$7_y } ← call rotate (struct SplineVector16) show_letter::via (byte) show_letter::angle
|
||||
@ -366,17 +364,9 @@ Adding struct value member variable copy (signed word) show_letter::current_x
|
||||
Adding struct value member variable copy (signed word) show_letter::current_y ← (signed word) show_letter::segment_to_y
|
||||
Replacing struct member reference (struct SplineVector16) show_letter::segment_to.x with member unwinding reference (signed word) show_letter::segment_to_x
|
||||
Replacing struct member reference (struct SplineVector16) show_letter::segment_to.y with member unwinding reference (signed word) show_letter::segment_to_y
|
||||
Rewriting struct pointer member access *((const struct Segment*) letter_c + (byte~) show_letter::$20).to
|
||||
Rewriting struct pointer member access *((const struct Segment*) letter_c + (byte~) show_letter::$20).to
|
||||
Rewriting struct pointer member access *((const struct Segment*) letter_c + (byte~) show_letter::$21).via
|
||||
Rewriting struct pointer member access *((const struct Segment*) letter_c + (byte~) show_letter::$21).via
|
||||
Rewriting struct pointer member access *((const struct Segment*) letter_c + (byte~) show_letter::$22).type
|
||||
Rewriting struct pointer member access *((const struct SplineVector16*) SPLINE_8SEG + (byte~) bitmap_plot_spline_8seg::$7).x
|
||||
Rewriting struct pointer member access *((const struct SplineVector16*) SPLINE_8SEG + (byte~) bitmap_plot_spline_8seg::$8).y
|
||||
Rewriting struct pointer member access *((struct SplineVector16*~) show_letter::$23 + (byte~) show_letter::$20).x
|
||||
Rewriting struct pointer member access *((struct SplineVector16*~) show_letter::$24 + (byte~) show_letter::$20).y
|
||||
Rewriting struct pointer member access *((struct SplineVector16*~) show_letter::$25 + (byte~) show_letter::$21).x
|
||||
Rewriting struct pointer member access *((struct SplineVector16*~) show_letter::$26 + (byte~) show_letter::$21).y
|
||||
Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src)
|
||||
Warning! Adding boolean cast to non-boolean condition *((byte*) strlen::str)
|
||||
Warning! Adding boolean cast to non-boolean condition (number~) abs_u16::$1
|
||||
@ -1414,12 +1404,12 @@ show_letter::@1: scope:[show_letter] from show_letter show_letter::@5
|
||||
(byte) show_letter::angle#1 ← phi( show_letter/(byte) show_letter::angle#3 show_letter::@5/(byte) show_letter::angle#4 )
|
||||
(byte) show_letter::i#2 ← phi( show_letter/(byte) show_letter::i#0 show_letter::@5/(byte) show_letter::i#1 )
|
||||
(byte~) show_letter::$20 ← (byte) show_letter::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
(struct SplineVector16*~) show_letter::$23 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(signed word*~) show_letter::$28 ← (signed word*)(struct SplineVector16*~) show_letter::$23 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
(signed word) show_letter::to_x#0 ← *((signed word*~) show_letter::$28 + (byte~) show_letter::$20)
|
||||
(struct SplineVector16*~) show_letter::$24 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(signed word*~) show_letter::$29 ← (signed word*)(struct SplineVector16*~) show_letter::$24 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
(signed word) show_letter::to_y#0 ← *((signed word*~) show_letter::$29 + (byte~) show_letter::$20)
|
||||
(signed word*~) show_letter::$24 ← (signed word*)(signed word*~) show_letter::$23 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
(signed word) show_letter::to_x#0 ← *((signed word*~) show_letter::$24 + (byte~) show_letter::$20)
|
||||
(signed word*~) show_letter::$23 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(signed word*~) show_letter::$26 ← (signed word*)(signed word*~) show_letter::$25 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
(signed word) show_letter::to_y#0 ← *((signed word*~) show_letter::$26 + (byte~) show_letter::$20)
|
||||
(signed word*~) show_letter::$25 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(number~) show_letter::$0 ← (signed word) show_letter::to_x#0 - (number) $32
|
||||
(number~) show_letter::$1 ← (signed word) show_letter::to_y#0 - (number) $96
|
||||
(signed word) show_letter::to_x#1 ← (signed word)(number~) show_letter::$0
|
||||
@ -1447,12 +1437,12 @@ show_letter::@11: scope:[show_letter] from show_letter::@1
|
||||
(signed word) show_letter::to_x#3 ← (signed word)(number~) show_letter::$3
|
||||
(signed word) show_letter::to_y#3 ← (signed word)(number~) show_letter::$4
|
||||
(byte~) show_letter::$21 ← (byte) show_letter::i#3 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
(struct SplineVector16*~) show_letter::$25 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
(signed word*~) show_letter::$30 ← (signed word*)(struct SplineVector16*~) show_letter::$25 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
(signed word) show_letter::via_x#0 ← *((signed word*~) show_letter::$30 + (byte~) show_letter::$21)
|
||||
(struct SplineVector16*~) show_letter::$26 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
(signed word*~) show_letter::$31 ← (signed word*)(struct SplineVector16*~) show_letter::$26 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
(signed word) show_letter::via_y#0 ← *((signed word*~) show_letter::$31 + (byte~) show_letter::$21)
|
||||
(signed word*~) show_letter::$28 ← (signed word*)(signed word*~) show_letter::$27 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
(signed word) show_letter::via_x#0 ← *((signed word*~) show_letter::$28 + (byte~) show_letter::$21)
|
||||
(signed word*~) show_letter::$27 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
(signed word*~) show_letter::$30 ← (signed word*)(signed word*~) show_letter::$29 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
(signed word) show_letter::via_y#0 ← *((signed word*~) show_letter::$30 + (byte~) show_letter::$21)
|
||||
(signed word*~) show_letter::$29 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
(number~) show_letter::$5 ← (signed word) show_letter::via_x#0 - (number) $32
|
||||
(number~) show_letter::$6 ← (signed word) show_letter::via_y#0 - (number) $96
|
||||
(signed word) show_letter::via_x#1 ← (signed word)(number~) show_letter::$5
|
||||
@ -1482,8 +1472,8 @@ show_letter::@12: scope:[show_letter] from show_letter::@11
|
||||
(signed word) show_letter::via_x#3 ← (signed word)(number~) show_letter::$8
|
||||
(signed word) show_letter::via_y#3 ← (signed word)(number~) show_letter::$9
|
||||
(byte~) show_letter::$22 ← (byte) show_letter::i#4 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
(byte*~) show_letter::$27 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TYPE
|
||||
(byte) show_letter::segment_type#0 ← *((byte*~) show_letter::$27 + (byte~) show_letter::$22)
|
||||
(byte*~) show_letter::$31 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TYPE
|
||||
(byte) show_letter::segment_type#0 ← *((byte*~) show_letter::$31 + (byte~) show_letter::$22)
|
||||
(signed word) show_letter::segment_to_x#0 ← (signed word) show_letter::to_x#4
|
||||
(signed word) show_letter::segment_to_y#0 ← (signed word) show_letter::to_y#4
|
||||
(signed word) show_letter::segment_via_x#0 ← (signed word) show_letter::via_x#3
|
||||
@ -2623,18 +2613,18 @@ SYMBOL TABLE SSA
|
||||
(byte~) show_letter::$20
|
||||
(byte~) show_letter::$21
|
||||
(byte~) show_letter::$22
|
||||
(struct SplineVector16*~) show_letter::$23
|
||||
(struct SplineVector16*~) show_letter::$24
|
||||
(struct SplineVector16*~) show_letter::$25
|
||||
(struct SplineVector16*~) show_letter::$26
|
||||
(byte*~) show_letter::$27
|
||||
(signed word*~) show_letter::$23
|
||||
(signed word*~) show_letter::$24
|
||||
(signed word*~) show_letter::$25
|
||||
(signed word*~) show_letter::$26
|
||||
(signed word*~) show_letter::$27
|
||||
(signed word*~) show_letter::$28
|
||||
(signed word*~) show_letter::$29
|
||||
(signed word~) show_letter::$2_x
|
||||
(signed word~) show_letter::$2_y
|
||||
(number~) show_letter::$3
|
||||
(signed word*~) show_letter::$30
|
||||
(signed word*~) show_letter::$31
|
||||
(byte*~) show_letter::$31
|
||||
(number~) show_letter::$4
|
||||
(number~) show_letter::$5
|
||||
(number~) show_letter::$6
|
||||
@ -3119,10 +3109,14 @@ Simplifying constant integer cast $fe
|
||||
Simplifying constant integer cast $ff
|
||||
Simplifying constant integer cast 9
|
||||
Simplifying constant integer cast $3e7
|
||||
Simplifying constant integer cast (signed word*~) show_letter::$23
|
||||
Simplifying constant integer cast (signed word*~) show_letter::$25
|
||||
Simplifying constant integer cast $32
|
||||
Simplifying constant integer cast $96
|
||||
Simplifying constant integer cast $64
|
||||
Simplifying constant integer cast $64
|
||||
Simplifying constant integer cast (signed word*~) show_letter::$27
|
||||
Simplifying constant integer cast (signed word*~) show_letter::$29
|
||||
Simplifying constant integer cast $32
|
||||
Simplifying constant integer cast $96
|
||||
Simplifying constant integer cast $64
|
||||
@ -3583,11 +3577,11 @@ Constant right-side identified [38] (signed word*~) spline_8segB::$34 ← (signe
|
||||
Constant right-side identified [56] (byte~) spline_8segB::$32 ← (byte) 8 * (const byte) SIZEOF_STRUCT_SPLINEVECTOR16
|
||||
Constant right-side identified [57] (signed word*~) spline_8segB::$35 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Constant right-side identified [59] (signed word*~) spline_8segB::$36 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant right-side identified [442] (struct SplineVector16*~) show_letter::$23 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant right-side identified [445] (struct SplineVector16*~) show_letter::$24 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant right-side identified [468] (struct SplineVector16*~) show_letter::$25 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant right-side identified [471] (struct SplineVector16*~) show_letter::$26 ← (struct SplineVector16*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant right-side identified [494] (byte*~) show_letter::$27 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TYPE
|
||||
Constant right-side identified [444] (signed word*~) show_letter::$23 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant right-side identified [447] (signed word*~) show_letter::$25 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant right-side identified [470] (signed word*~) show_letter::$27 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant right-side identified [473] (signed word*~) show_letter::$29 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant right-side identified [494] (byte*~) show_letter::$31 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TYPE
|
||||
Constant right-side identified [539] (byte~) bitmap_plot_spline_8seg::$6 ← (byte) 0 * (const byte) SIZEOF_STRUCT_SPLINEVECTOR16
|
||||
Constant right-side identified [540] (signed word*~) bitmap_plot_spline_8seg::$10 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Constant right-side identified [542] (signed word*~) bitmap_plot_spline_8seg::$11 ← (signed word*)(const struct SplineVector16*) SPLINE_8SEG + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
@ -3637,11 +3631,11 @@ Constant (const byte) main::w#0 = 0
|
||||
Constant (const signed word) show_letter::current_x#0 = 0
|
||||
Constant (const signed word) show_letter::current_y#0 = 0
|
||||
Constant (const byte) show_letter::i#0 = 0
|
||||
Constant (const struct SplineVector16*) show_letter::$23 = (struct SplineVector16*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant (const struct SplineVector16*) show_letter::$24 = (struct SplineVector16*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant (const struct SplineVector16*) show_letter::$25 = (struct SplineVector16*)letter_c+OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant (const struct SplineVector16*) show_letter::$26 = (struct SplineVector16*)letter_c+OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant (const byte*) show_letter::$27 = (byte*)letter_c+OFFSET_STRUCT_SEGMENT_TYPE
|
||||
Constant (const signed word*) show_letter::$23 = (signed word*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant (const signed word*) show_letter::$25 = (signed word*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant (const signed word*) show_letter::$27 = (signed word*)letter_c+OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant (const signed word*) show_letter::$29 = (signed word*)letter_c+OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant (const byte*) show_letter::$31 = (byte*)letter_c+OFFSET_STRUCT_SEGMENT_TYPE
|
||||
Constant (const byte) bitmap_plot_spline_8seg::$6 = 0*SIZEOF_STRUCT_SPLINEVECTOR16
|
||||
Constant (const signed word*) bitmap_plot_spline_8seg::$10 = (signed word*)SPLINE_8SEG+OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Constant (const signed word*) bitmap_plot_spline_8seg::$11 = (signed word*)SPLINE_8SEG+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
@ -3660,11 +3654,6 @@ Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const void*) memset::str#0 = (void*)bitmap_screen#1
|
||||
Constant (const void*) memset::str#1 = (void*)bitmap_gfx#1
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant value identified (signed word*)show_letter::$23 in [443] (signed word*~) show_letter::$28 ← (signed word*)(const struct SplineVector16*) show_letter::$23 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Constant value identified (signed word*)show_letter::$24 in [446] (signed word*~) show_letter::$29 ← (signed word*)(const struct SplineVector16*) show_letter::$24 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant value identified (signed word*)show_letter::$25 in [469] (signed word*~) show_letter::$30 ← (signed word*)(const struct SplineVector16*) show_letter::$25 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Constant value identified (signed word*)show_letter::$26 in [472] (signed word*~) show_letter::$31 ← (signed word*)(const struct SplineVector16*) show_letter::$26 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantValues
|
||||
if() condition always true - replacing block destination [406] if(true) goto main::@2
|
||||
if() condition always true - replacing block destination [429] if(true) goto main::@14
|
||||
Successful SSA optimization Pass2ConstantIfs
|
||||
@ -3688,8 +3677,8 @@ Simplifying expression containing zero (byte*)letter_c in
|
||||
Simplifying expression containing zero (signed word*)SPLINE_8SEG in
|
||||
Simplifying expression containing zero (signed word*)SPLINE_8SEG in
|
||||
Simplifying expression containing zero (signed word*)SPLINE_8SEG in
|
||||
Simplifying expression containing zero (signed word*)show_letter::$23 in [443] (signed word*~) show_letter::$28 ← (signed word*)(const struct SplineVector16*) show_letter::$23 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Simplifying expression containing zero (signed word*)show_letter::$25 in [469] (signed word*~) show_letter::$30 ← (signed word*)(const struct SplineVector16*) show_letter::$25 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Simplifying expression containing zero show_letter::$23 in [442] (signed word*~) show_letter::$24 ← (const signed word*) show_letter::$23 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Simplifying expression containing zero show_letter::$27 in [468] (signed word*~) show_letter::$28 ← (const signed word*) show_letter::$27 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Simplifying expression containing zero bitmap_plot_spline_8seg::$10 in [541] (signed word) bitmap_plot_spline_8seg::current_x#0 ← *((const signed word*) bitmap_plot_spline_8seg::$10 + (const byte) bitmap_plot_spline_8seg::$6)
|
||||
Simplifying expression containing zero bitmap_plot_spline_8seg::$11 in [543] (signed word) bitmap_plot_spline_8seg::current_y#0 ← *((const signed word*) bitmap_plot_spline_8seg::$11 + (const byte) bitmap_plot_spline_8seg::$6)
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
@ -3761,16 +3750,16 @@ Successful SSA optimization Pass2ConditionalJumpSequenceImprovement
|
||||
Constant right-side identified [207] (byte~) main::vicSelectGfxBank1_toDd001_$1 ← > (const word) main::vicSelectGfxBank1_toDd001_$0
|
||||
Constant right-side identified [211] (word~) main::toD0181_$1 ← (const word) main::toD0181_$0 & (word) $3fff
|
||||
Constant right-side identified [214] (byte~) main::toD0181_$5 ← > (const word) main::toD0181_$4
|
||||
Constant right-side identified [234] (signed word*~) show_letter::$29 ← (signed word*)(const struct SplineVector16*) show_letter::$24 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant right-side identified [255] (signed word*~) show_letter::$31 ← (signed word*)(const struct SplineVector16*) show_letter::$26 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant right-side identified [234] (signed word*~) show_letter::$26 ← (const signed word*) show_letter::$25 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant right-side identified [255] (signed word*~) show_letter::$30 ← (const signed word*) show_letter::$29 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::vicSelectGfxBank1_toDd001_$1 = >main::vicSelectGfxBank1_toDd001_$0
|
||||
Constant (const word) main::toD0181_$1 = main::toD0181_$0&$3fff
|
||||
Constant (const byte) main::toD0181_$5 = >main::toD0181_$4
|
||||
Constant (const signed word*) show_letter::$28 = (signed word*)show_letter::$23
|
||||
Constant (const signed word*) show_letter::$29 = (signed word*)show_letter::$24+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant (const signed word*) show_letter::$30 = (signed word*)show_letter::$25
|
||||
Constant (const signed word*) show_letter::$31 = (signed word*)show_letter::$26+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant (const signed word*) show_letter::$24 = show_letter::$23
|
||||
Constant (const signed word*) show_letter::$26 = show_letter::$25+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant (const signed word*) show_letter::$28 = show_letter::$27
|
||||
Constant (const signed word*) show_letter::$30 = show_letter::$29+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Eliminating unused constant (const byte*) PRINT_SCREEN
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
@ -3885,13 +3874,13 @@ Constant inlined bitmap_gfx#1 = (const byte*) BITMAP_GRAPHICS
|
||||
Constant inlined main::toD0181_$0 = (word)(const byte*) BITMAP_SCREEN
|
||||
Constant inlined show_letter::current_x#0 = (signed word) 0
|
||||
Constant inlined main::toD0181_$6 = >(word)(const byte*) BITMAP_GRAPHICS/(byte) 4
|
||||
Constant inlined show_letter::$24 = (struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined show_letter::$24 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::toD0181_$5 = >(word)(const byte*) BITMAP_GRAPHICS
|
||||
Constant inlined show_letter::$25 = (struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant inlined show_letter::$25 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::w#0 = (byte) 0
|
||||
Constant inlined main::toD0181_$4 = (word)(const byte*) BITMAP_GRAPHICS
|
||||
Constant inlined show_letter::$23 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::toD0181_$3 = >(word)(const byte*) BITMAP_SCREEN&(word) $3fff*(byte) 4
|
||||
Constant inlined show_letter::$23 = (struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined bitmap_plot_spline_8seg::$12 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG
|
||||
Constant inlined bitmap_plot_spline_8seg::$13 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined bitmap_plot_spline_8seg::$14 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG
|
||||
@ -3906,19 +3895,19 @@ Constant inlined bitmap_plot_spline_8seg::$11 = (signed word*)(const struct Spli
|
||||
Constant inlined mulf_init::c#0 = (byte) 0
|
||||
Constant inlined main::toD0181_screen#0 = (const byte*) BITMAP_SCREEN
|
||||
Constant inlined main::toD0181_gfx#0 = (const byte*) BITMAP_GRAPHICS
|
||||
Constant inlined show_letter::$31 = (signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined show_letter::$30 = (signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant inlined show_letter::$31 = (byte*)(const struct Segment*) letter_c
|
||||
Constant inlined show_letter::$30 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined bitmap_init::bits#0 = (byte) $80
|
||||
Constant inlined spline_8segB::$36 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined bitmap_init::bits#2 = (byte) $80
|
||||
Constant inlined spline_8segB::$32 = (byte) 8*(const byte) SIZEOF_STRUCT_SPLINEVECTOR16
|
||||
Constant inlined show_letter::$28 = (signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined show_letter::$28 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant inlined spline_8segB::$33 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG
|
||||
Constant inlined show_letter::$29 = (signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined show_letter::$29 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant inlined spline_8segB::$34 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined show_letter::$26 = (struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant inlined show_letter::$26 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined show_letter::$27 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA
|
||||
Constant inlined spline_8segB::$35 = (signed word*)(const struct SplineVector16*) SPLINE_8SEG
|
||||
Constant inlined show_letter::$27 = (byte*)(const struct Segment*) letter_c
|
||||
Constant inlined sgn_u16::return#3 = (byte) 1
|
||||
Constant inlined sgn_u16::return#2 = (byte) -1
|
||||
Constant inlined memset::str#1 = (void*)(const byte*) BITMAP_GRAPHICS
|
||||
@ -4316,8 +4305,8 @@ show_letter::@1: scope:[show_letter] from show_letter show_letter::@9
|
||||
[28] (byte) show_letter::i#10 ← phi( show_letter/(byte) 0 show_letter::@9/(byte) show_letter::i#1 )
|
||||
[29] (byte~) show_letter::$32 ← (byte) show_letter::i#10 << (byte) 3
|
||||
[30] (byte~) show_letter::$20 ← (byte~) show_letter::$32 + (byte) show_letter::i#10
|
||||
[31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20)
|
||||
[32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20)
|
||||
[31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20)
|
||||
[32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20)
|
||||
[33] (signed word) show_letter::to_x#1 ← (signed word) show_letter::to_x#0 - (signed byte) $32
|
||||
[34] (signed word) show_letter::to_y#1 ← (signed word) show_letter::to_y#0 - (signed word) $96
|
||||
[35] (signed word) rotate::vector_x#0 ← (signed word) show_letter::to_x#1
|
||||
@ -4334,8 +4323,8 @@ show_letter::@6: scope:[show_letter] from show_letter::@1
|
||||
[44] (signed word) show_letter::current_y#10 ← (signed word) show_letter::to_y#2 + (signed byte) $64
|
||||
[45] (byte~) show_letter::$34 ← (byte) show_letter::i#10 << (byte) 3
|
||||
[46] (byte~) show_letter::$21 ← (byte~) show_letter::$34 + (byte) show_letter::i#10
|
||||
[47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21)
|
||||
[48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21)
|
||||
[47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21)
|
||||
[48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21)
|
||||
[49] (signed word) show_letter::via_x#1 ← (signed word) show_letter::via_x#0 - (signed byte) $32
|
||||
[50] (signed word) show_letter::via_y#1 ← (signed word) show_letter::via_y#0 - (signed word) $96
|
||||
[51] (signed word) rotate::vector_x#1 ← (signed word) show_letter::via_x#1
|
||||
@ -5984,13 +5973,13 @@ show_letter: {
|
||||
clc
|
||||
adc.z i
|
||||
sta.z __20
|
||||
// [31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
// [31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
ldy.z __20
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,y
|
||||
sta.z to_x+1
|
||||
// [32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
// [32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
ldy.z __20
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
@ -6082,13 +6071,13 @@ show_letter: {
|
||||
clc
|
||||
adc.z i
|
||||
sta.z __21
|
||||
// [47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
// [47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
ldy.z __21
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA,y
|
||||
sta.z via_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+1,y
|
||||
sta.z via_x+1
|
||||
// [48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
// [48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
ldy.z __21
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z via_y
|
||||
@ -8428,9 +8417,9 @@ Statement [29] (byte~) show_letter::$32 ← (byte) show_letter::i#10 << (byte) 3
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:83 [ show_letter::angle#0 ]
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:4 [ show_letter::i#10 show_letter::i#1 ]
|
||||
Statement [30] (byte~) show_letter::$20 ← (byte~) show_letter::$32 + (byte) show_letter::i#10 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 ] ) always clobbers reg byte a
|
||||
Statement [31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ) always clobbers reg byte a
|
||||
Statement [31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:85 [ show_letter::$20 ]
|
||||
Statement [32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [33] (signed word) show_letter::to_x#1 ← (signed word) show_letter::to_x#0 - (signed byte) $32 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#0 show_letter::to_x#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#0 show_letter::to_x#1 ] ) always clobbers reg byte a
|
||||
Statement [34] (signed word) show_letter::to_y#1 ← (signed word) show_letter::to_y#0 - (signed word) $96 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#1 show_letter::to_y#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#1 show_letter::to_y#1 ] ) always clobbers reg byte a
|
||||
Statement [35] (signed word) rotate::vector_x#0 ← (signed word) show_letter::to_x#1 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#1 rotate::vector_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#1 rotate::vector_x#0 ] ) always clobbers reg byte a
|
||||
@ -8443,9 +8432,9 @@ Statement [43] (signed word) show_letter::current_x#10 ← (signed word) show_le
|
||||
Statement [44] (signed word) show_letter::current_y#10 ← (signed word) show_letter::to_y#2 + (signed byte) $64 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 ] ) always clobbers reg byte a
|
||||
Statement [45] (byte~) show_letter::$34 ← (byte) show_letter::i#10 << (byte) 3 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$34 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$34 ] ) always clobbers reg byte a
|
||||
Statement [46] (byte~) show_letter::$21 ← (byte~) show_letter::$34 + (byte) show_letter::i#10 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 ] ) always clobbers reg byte a
|
||||
Statement [47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ) always clobbers reg byte a
|
||||
Statement [47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:107 [ show_letter::$21 ]
|
||||
Statement [48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ) always clobbers reg byte a
|
||||
Statement [48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ) always clobbers reg byte a
|
||||
Statement [49] (signed word) show_letter::via_x#1 ← (signed word) show_letter::via_x#0 - (signed byte) $32 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#0 show_letter::via_x#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#0 show_letter::via_x#1 ] ) always clobbers reg byte a
|
||||
Statement [50] (signed word) show_letter::via_y#1 ← (signed word) show_letter::via_y#0 - (signed word) $96 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#1 show_letter::via_y#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#1 show_letter::via_y#1 ] ) always clobbers reg byte a
|
||||
Statement [51] (signed word) rotate::vector_x#1 ← (signed word) show_letter::via_x#1 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#1 rotate::vector_x#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#1 rotate::vector_x#1 ] ) always clobbers reg byte a
|
||||
@ -8664,8 +8653,8 @@ Statement [23] if(*((const byte*) RASTER)!=(byte) $ff) goto main::@4 [ main::ang
|
||||
Statement [26] (byte) main::angle#1 ← (byte) main::angle#2 + (byte) 9 [ main::angle#1 ] ( main:2 [ main::angle#1 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [29] (byte~) show_letter::$32 ← (byte) show_letter::i#10 << (byte) 3 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$32 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$32 ] ) always clobbers reg byte a
|
||||
Statement [30] (byte~) show_letter::$20 ← (byte~) show_letter::$32 + (byte) show_letter::i#10 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 ] ) always clobbers reg byte a
|
||||
Statement [31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ) always clobbers reg byte a
|
||||
Statement [32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::$20 show_letter::to_x#0 ] ) always clobbers reg byte a
|
||||
Statement [32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#0 show_letter::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [33] (signed word) show_letter::to_x#1 ← (signed word) show_letter::to_x#0 - (signed byte) $32 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#0 show_letter::to_x#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#0 show_letter::to_x#1 ] ) always clobbers reg byte a
|
||||
Statement [34] (signed word) show_letter::to_y#1 ← (signed word) show_letter::to_y#0 - (signed word) $96 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#1 show_letter::to_y#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_x#1 show_letter::to_y#1 ] ) always clobbers reg byte a
|
||||
Statement [35] (signed word) rotate::vector_x#0 ← (signed word) show_letter::to_x#1 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#1 rotate::vector_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::to_y#1 rotate::vector_x#0 ] ) always clobbers reg byte a
|
||||
@ -8678,8 +8667,8 @@ Statement [43] (signed word) show_letter::current_x#10 ← (signed word) show_le
|
||||
Statement [44] (signed word) show_letter::current_y#10 ← (signed word) show_letter::to_y#2 + (signed byte) $64 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 ] ) always clobbers reg byte a
|
||||
Statement [45] (byte~) show_letter::$34 ← (byte) show_letter::i#10 << (byte) 3 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$34 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$34 ] ) always clobbers reg byte a
|
||||
Statement [46] (byte~) show_letter::$21 ← (byte~) show_letter::$34 + (byte) show_letter::i#10 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 ] ) always clobbers reg byte a
|
||||
Statement [47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ) always clobbers reg byte a
|
||||
Statement [48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ) always clobbers reg byte a
|
||||
Statement [47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::$21 show_letter::via_x#0 ] ) always clobbers reg byte a
|
||||
Statement [48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#0 show_letter::via_y#0 ] ) always clobbers reg byte a
|
||||
Statement [49] (signed word) show_letter::via_x#1 ← (signed word) show_letter::via_x#0 - (signed byte) $32 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#0 show_letter::via_x#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#0 show_letter::via_x#1 ] ) always clobbers reg byte a
|
||||
Statement [50] (signed word) show_letter::via_y#1 ← (signed word) show_letter::via_y#0 - (signed word) $96 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#1 show_letter::via_y#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_x#1 show_letter::via_y#1 ] ) always clobbers reg byte a
|
||||
Statement [51] (signed word) rotate::vector_x#1 ← (signed word) show_letter::via_x#1 [ show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#1 rotate::vector_x#1 ] ( main:2::show_letter:20 [ main::angle#2 show_letter::angle#0 show_letter::i#10 show_letter::current_x#4 show_letter::current_y#4 show_letter::current_x#10 show_letter::current_y#10 show_letter::via_y#1 rotate::vector_x#1 ] ) always clobbers reg byte a
|
||||
@ -9449,12 +9438,12 @@ show_letter: {
|
||||
clc
|
||||
adc.z i
|
||||
tax
|
||||
// [31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,x
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,x
|
||||
sta.z to_x+1
|
||||
// [32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,x
|
||||
sta.z to_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,x
|
||||
@ -9518,12 +9507,12 @@ show_letter: {
|
||||
clc
|
||||
adc.z i
|
||||
tax
|
||||
// [47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA,x
|
||||
sta.z via_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+1,x
|
||||
sta.z via_x+1
|
||||
// [48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+OFFSET_STRUCT_SPLINEVECTOR16_Y,x
|
||||
sta.z via_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,x
|
||||
@ -12524,7 +12513,7 @@ show_letter: {
|
||||
sta.z i
|
||||
// show_letter::@1
|
||||
__b1:
|
||||
// to = { letter_c[i].to.x, letter_c[i].to.y }
|
||||
// to = letter_c[i].to
|
||||
// [29] (byte~) show_letter::$32 ← (byte) show_letter::i#10 << (byte) 3 -- vbuaa=vbuz1_rol_3
|
||||
lda.z i
|
||||
asl
|
||||
@ -12534,12 +12523,12 @@ show_letter: {
|
||||
clc
|
||||
adc.z i
|
||||
tax
|
||||
// [31] (signed word) show_letter::to_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [31] (signed word) show_letter::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,x
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,x
|
||||
sta.z to_x+1
|
||||
// [32] (signed word) show_letter::to_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [32] (signed word) show_letter::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$20) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,x
|
||||
sta.z to_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,x
|
||||
@ -12596,7 +12585,7 @@ show_letter: {
|
||||
lda.z to_y_1+1
|
||||
adc #>$64
|
||||
sta.z current_y_1+1
|
||||
// via = { letter_c[i].via.x, letter_c[i].via.y }
|
||||
// via = letter_c[i].via
|
||||
// [45] (byte~) show_letter::$34 ← (byte) show_letter::i#10 << (byte) 3 -- vbuaa=vbuz1_rol_3
|
||||
lda.z i
|
||||
asl
|
||||
@ -12606,12 +12595,12 @@ show_letter: {
|
||||
clc
|
||||
adc.z i
|
||||
tax
|
||||
// [47] (signed word) show_letter::via_x#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [47] (signed word) show_letter::via_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA,x
|
||||
sta.z via_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+1,x
|
||||
sta.z via_x+1
|
||||
// [48] (signed word) show_letter::via_y#0 ← *((signed word*)(struct SplineVector16*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
// [48] (signed word) show_letter::via_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_VIA+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) show_letter::$21) -- vwsz1=pwsc1_derefidx_vbuxx
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+OFFSET_STRUCT_SPLINEVECTOR16_Y,x
|
||||
sta.z via_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_VIA+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,x
|
||||
|
43
src/test/ref/struct-37.asm
Normal file
43
src/test/ref/struct-37.asm
Normal file
@ -0,0 +1,43 @@
|
||||
// Complex C-struct - copying a sub-struct from C-standard layout to Unwound layout
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 1
|
||||
main: {
|
||||
.label to_x = 3
|
||||
.label to_y = 4
|
||||
.label j = 2
|
||||
lda #0
|
||||
sta.z j
|
||||
tax
|
||||
__b1:
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
stx.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
tay
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
lda.z to_x
|
||||
ldy.z j
|
||||
sta SCREEN,y
|
||||
iny
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
iny
|
||||
sty.z j
|
||||
inx
|
||||
cpx #3
|
||||
bne __b1
|
||||
rts
|
||||
}
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO, 'a', 'b', 0, 0, SPLINE_TO, 'c', 'd', $67, $a9, SPLINE_TO, 'e', 'f', $4b, $c3
|
31
src/test/ref/struct-37.cfg
Normal file
31
src/test/ref/struct-37.cfg
Normal file
@ -0,0 +1,31 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::j#3 ← phi( main/(byte) 0 main::@1/(byte) main::j#2 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2
|
||||
[7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2
|
||||
[8] (byte) main::to_x#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1)
|
||||
[9] (byte) main::to_y#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1)
|
||||
[10] *((const byte*) SCREEN + (byte) main::j#3) ← (byte) main::to_x#0
|
||||
[11] (byte) main::j#1 ← ++ (byte) main::j#3
|
||||
[12] *((const byte*) SCREEN + (byte) main::j#1) ← (byte) main::to_y#0
|
||||
[13] (byte) main::j#2 ← ++ (byte) main::j#1
|
||||
[14] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[15] if((byte) main::i#1!=(byte) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[16] return
|
||||
to:@return
|
630
src/test/ref/struct-37.log
Normal file
630
src/test/ref/struct-37.log
Normal file
@ -0,0 +1,630 @@
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) main::i)
|
||||
Created struct value member variable (byte) main::to_x
|
||||
Created struct value member variable (byte) main::to_y
|
||||
Converted struct value to member variables (struct SplineVector16) main::to
|
||||
Adding struct value member variable copy (byte) main::to_x ← *((byte*~) main::$3 + (byte~) main::$1)
|
||||
Adding struct value member variable copy (byte) main::to_y ← *((byte*~) main::$5 + (byte~) main::$1)
|
||||
Replacing struct member reference (struct SplineVector16) main::to.x with member unwinding reference (byte) main::to_x
|
||||
Replacing struct member reference (struct SplineVector16) main::to.y with member unwinding reference (byte) main::to_y
|
||||
Culled Empty Block (label) main::@2
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
(byte) main::j#0 ← (byte) 0
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::j#3 ← phi( main/(byte) main::j#0 main::@1/(byte) main::j#2 )
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
(byte~) main::$1 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
(byte*~) main::$3 ← (byte*)(byte*~) main::$2 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
(byte) main::to_x#0 ← *((byte*~) main::$3 + (byte~) main::$1)
|
||||
(byte*~) main::$2 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(byte*~) main::$5 ← (byte*)(byte*~) main::$4 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
(byte) main::to_y#0 ← *((byte*~) main::$5 + (byte~) main::$1)
|
||||
(byte*~) main::$4 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
*((const byte*) SCREEN + (byte) main::j#3) ← (byte) main::to_x#0
|
||||
(byte) main::j#1 ← ++ (byte) main::j#3
|
||||
*((const byte*) SCREEN + (byte) main::j#1) ← (byte) main::to_y#0
|
||||
(byte) main::j#2 ← ++ (byte) main::j#1
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,2)
|
||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,2)
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_X = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y = (byte) 1
|
||||
(const byte*) SCREEN = (byte*)(number) $400
|
||||
(const byte) SIZEOF_STRUCT_SEGMENT = (byte) 5
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(byte) SplineVector16::x
|
||||
(byte) SplineVector16::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (byte) 'a', y: (byte) 'b' }, via: { x: (byte) 0, y: (byte) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (byte) 'c', y: (byte) 'd' }, via: { x: (byte) $67, y: (byte) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (byte) 'e', y: (byte) 'f' }, via: { x: (byte) $4b, y: (byte) $c3 } } }
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(byte~) main::$1
|
||||
(byte*~) main::$2
|
||||
(byte*~) main::$3
|
||||
(byte*~) main::$4
|
||||
(byte*~) main::$5
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
(byte) main::j
|
||||
(byte) main::j#0
|
||||
(byte) main::j#1
|
||||
(byte) main::j#2
|
||||
(byte) main::j#3
|
||||
(byte) main::to_x
|
||||
(byte) main::to_x#0
|
||||
(byte) main::to_y
|
||||
(byte) main::to_y#0
|
||||
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast (byte*~) main::$2
|
||||
Simplifying constant integer cast (byte*~) main::$4
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Simple Condition (bool~) main::$0 [16] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant right-side identified [6] (byte*~) main::$2 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant right-side identified [9] (byte*~) main::$4 ← (byte*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::j#0 = 0
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Constant (const byte*) main::$2 = (byte*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant (const byte*) main::$4 = (byte*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [14] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [16] if(main::i#1!=rangelast(0,2)) goto main::@1 to (number) 3
|
||||
Simplifying expression containing zero main::$2 in [4] (byte*~) main::$3 ← (const byte*) main::$2 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding number conversion cast (unumber) 3 in if((byte) main::i#1!=(number) 3) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant integer cast 3
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 3
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Constant right-side identified [4] (byte*~) main::$5 ← (const byte*) main::$4 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte*) main::$3 = main::$2
|
||||
Constant (const byte*) main::$5 = main::$4+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Rewriting multiplication to use shift and addition[1] (byte~) main::$1 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
Inlining constant with var siblings (const byte) main::j#0
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Constant inlined main::$5 = (byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Constant inlined main::i#0 = (byte) 0
|
||||
Constant inlined main::$3 = (byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::$4 = (byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::j#0 = (byte) 0
|
||||
Constant inlined main::$2 = (byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Alias (byte~) main::$1 = (byte~) main::$7
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Eliminating unused constant (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced [18] main::i#3 ← main::i#1
|
||||
Coalesced [19] main::j#4 ← main::j#2
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) @2
|
||||
Culled Empty Block (label) main::@3
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::j#3 ← phi( main/(byte) 0 main::@1/(byte) main::j#2 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2
|
||||
[7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2
|
||||
[8] (byte) main::to_x#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1)
|
||||
[9] (byte) main::to_y#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1)
|
||||
[10] *((const byte*) SCREEN + (byte) main::j#3) ← (byte) main::to_x#0
|
||||
[11] (byte) main::j#1 ← ++ (byte) main::j#3
|
||||
[12] *((const byte*) SCREEN + (byte) main::j#1) ← (byte) main::to_y#0
|
||||
[13] (byte) main::j#2 ← ++ (byte) main::j#1
|
||||
[14] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[15] if((byte) main::i#1!=(byte) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[16] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(byte) SplineVector16::x
|
||||
(byte) SplineVector16::y
|
||||
(void()) main()
|
||||
(byte~) main::$1 16.5
|
||||
(byte~) main::$6 22.0
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 4.888888888888889
|
||||
(byte) main::j
|
||||
(byte) main::j#1 16.5
|
||||
(byte) main::j#2 7.333333333333333
|
||||
(byte) main::j#3 5.5
|
||||
(byte) main::to_x
|
||||
(byte) main::to_x#0 11.0
|
||||
(byte) main::to_y
|
||||
(byte) main::to_y#0 7.333333333333333
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::j#3 main::j#2 ]
|
||||
Added variable main::$6 to live range equivalence class [ main::$6 ]
|
||||
Added variable main::$1 to live range equivalence class [ main::$1 ]
|
||||
Added variable main::to_x#0 to live range equivalence class [ main::to_x#0 ]
|
||||
Added variable main::to_y#0 to live range equivalence class [ main::to_y#0 ]
|
||||
Added variable main::j#1 to live range equivalence class [ main::j#1 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::j#3 main::j#2 ]
|
||||
[ main::$6 ]
|
||||
[ main::$1 ]
|
||||
[ main::to_x#0 ]
|
||||
[ main::to_y#0 ]
|
||||
[ main::j#1 ]
|
||||
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Allocated zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Allocated zp[1]:4 [ main::$6 ]
|
||||
Allocated zp[1]:5 [ main::$1 ]
|
||||
Allocated zp[1]:6 [ main::to_x#0 ]
|
||||
Allocated zp[1]:7 [ main::to_y#0 ]
|
||||
Allocated zp[1]:8 [ main::j#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct from C-standard layout to Unwound layout
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 1
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label __1 = 5
|
||||
.label to_x = 6
|
||||
.label to_y = 7
|
||||
.label j = 8
|
||||
.label j_1 = 3
|
||||
.label i = 2
|
||||
.label __6 = 4
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j_1
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2 -- vbuz1=vbuz2_rol_2
|
||||
lda.z i
|
||||
asl
|
||||
asl
|
||||
sta.z __6
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z __6
|
||||
clc
|
||||
adc.z i
|
||||
sta.z __1
|
||||
// [8] (byte) main::to_x#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) -- vbuz1=pbuc1_derefidx_vbuz2
|
||||
ldy.z __1
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
// [9] (byte) main::to_y#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) -- vbuz1=pbuc1_derefidx_vbuz2
|
||||
ldy.z __1
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
// [10] *((const byte*) SCREEN + (byte) main::j#3) ← (byte) main::to_x#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z to_x
|
||||
ldy.z j_1
|
||||
sta SCREEN,y
|
||||
// [11] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuz1=_inc_vbuz2
|
||||
ldy.z j_1
|
||||
iny
|
||||
sty.z j
|
||||
// [12] *((const byte*) SCREEN + (byte) main::j#1) ← (byte) main::to_y#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z to_y
|
||||
ldy.z j
|
||||
sta SCREEN,y
|
||||
// [13] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuz2
|
||||
ldy.z j
|
||||
iny
|
||||
sty.z j_1
|
||||
// [14] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [15] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #3
|
||||
cmp.z i
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO, 'a', 'b', 0, 0, SPLINE_TO, 'c', 'd', $67, $a9, SPLINE_TO, 'e', 'f', $4b, $c3
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2 [ main::i#2 main::j#3 main::$6 ] ( main:2 [ main::i#2 main::j#3 main::$6 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Statement [7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2 [ main::i#2 main::j#3 main::$1 ] ( main:2 [ main::i#2 main::j#3 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2 [ main::i#2 main::j#3 main::$6 ] ( main:2 [ main::i#2 main::j#3 main::$6 ] ) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2 [ main::i#2 main::j#3 main::$1 ] ( main:2 [ main::i#2 main::j#3 main::$1 ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:3 [ main::j#3 main::j#2 ] : zp[1]:3 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:4 [ main::$6 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ main::$1 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:6 [ main::to_x#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:7 [ main::to_y#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:8 [ main::j#1 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 22: zp[1]:4 [ main::$6 ] 21.39: zp[1]:2 [ main::i#2 main::i#1 ] 16.5: zp[1]:5 [ main::$1 ] 16.5: zp[1]:8 [ main::j#1 ] 12.83: zp[1]:3 [ main::j#3 main::j#2 ] 11: zp[1]:6 [ main::to_x#0 ] 7.33: zp[1]:7 [ main::to_y#0 ]
|
||||
Uplift Scope [SplineVector16]
|
||||
Uplift Scope [Segment]
|
||||
Uplift Scope [Segment::SegmentType]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 933 combination reg byte a [ main::$6 ] reg byte x [ main::i#2 main::i#1 ] reg byte y [ main::$1 ] zp[1]:8 [ main::j#1 ] zp[1]:3 [ main::j#3 main::j#2 ] zp[1]:6 [ main::to_x#0 ] zp[1]:7 [ main::to_y#0 ]
|
||||
Limited combination testing to 100 combinations of 9216 possible.
|
||||
Uplifting [SplineVector16] best 933 combination
|
||||
Uplifting [Segment] best 933 combination
|
||||
Uplifting [Segment::SegmentType] best 933 combination
|
||||
Uplifting [] best 933 combination
|
||||
Attempting to uplift remaining variables inzp[1]:8 [ main::j#1 ]
|
||||
Uplifting [main] best 843 combination reg byte y [ main::j#1 ]
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Uplifting [main] best 843 combination zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Attempting to uplift remaining variables inzp[1]:6 [ main::to_x#0 ]
|
||||
Uplifting [main] best 843 combination zp[1]:6 [ main::to_x#0 ]
|
||||
Attempting to uplift remaining variables inzp[1]:7 [ main::to_y#0 ]
|
||||
Uplifting [main] best 843 combination zp[1]:7 [ main::to_y#0 ]
|
||||
Allocated (was zp[1]:3) zp[1]:2 [ main::j#3 main::j#2 ]
|
||||
Allocated (was zp[1]:6) zp[1]:3 [ main::to_x#0 ]
|
||||
Allocated (was zp[1]:7) zp[1]:4 [ main::to_y#0 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct from C-standard layout to Unwound layout
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 1
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label to_x = 3
|
||||
.label to_y = 4
|
||||
.label j = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2 -- vbuaa=vbuxx_rol_2
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2 -- vbuyy=vbuaa_plus_vbuxx
|
||||
stx.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
tay
|
||||
// [8] (byte) main::to_x#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) -- vbuz1=pbuc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
// [9] (byte) main::to_y#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) -- vbuz1=pbuc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
// [10] *((const byte*) SCREEN + (byte) main::j#3) ← (byte) main::to_x#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z to_x
|
||||
ldy.z j
|
||||
sta SCREEN,y
|
||||
// [11] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuyy=_inc_vbuz1
|
||||
ldy.z j
|
||||
iny
|
||||
// [12] *((const byte*) SCREEN + (byte) main::j#1) ← (byte) main::to_y#0 -- pbuc1_derefidx_vbuyy=vbuz1
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
// [13] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuyy
|
||||
iny
|
||||
sty.z j
|
||||
// [14] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [15] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #3
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO, 'a', 'b', 0, 0, SPLINE_TO, 'c', 'd', $67, $a9, SPLINE_TO, 'e', 'f', $4b, $c3
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __bend
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing instruction ldx #0 with TAX
|
||||
Removing instruction ldy.z j
|
||||
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||
Replacing label __bbegin with __b1
|
||||
Replacing label __b1_from___b1 with __b1
|
||||
Removing instruction __bbegin:
|
||||
Removing instruction __b1_from___bbegin:
|
||||
Removing instruction main_from___b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Removing instruction __b1_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction jmp __b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __b1:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y = (byte) 1
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(byte) SplineVector16::x
|
||||
(byte) SplineVector16::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (byte) 'a', y: (byte) 'b' }, via: { x: (byte) 0, y: (byte) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (byte) 'c', y: (byte) 'd' }, via: { x: (byte) $67, y: (byte) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (byte) 'e', y: (byte) 'f' }, via: { x: (byte) $4b, y: (byte) $c3 } } }
|
||||
(void()) main()
|
||||
(byte~) main::$1 reg byte y 16.5
|
||||
(byte~) main::$6 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 4.888888888888889
|
||||
(byte) main::j
|
||||
(byte) main::j#1 reg byte y 16.5
|
||||
(byte) main::j#2 j zp[1]:2 7.333333333333333
|
||||
(byte) main::j#3 j zp[1]:2 5.5
|
||||
(byte) main::to_x
|
||||
(byte) main::to_x#0 to_x zp[1]:3 11.0
|
||||
(byte) main::to_y
|
||||
(byte) main::to_y#0 to_y zp[1]:4 7.333333333333333
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp[1]:2 [ main::j#3 main::j#2 ]
|
||||
reg byte a [ main::$6 ]
|
||||
reg byte y [ main::$1 ]
|
||||
zp[1]:3 [ main::to_x#0 ]
|
||||
zp[1]:4 [ main::to_y#0 ]
|
||||
reg byte y [ main::j#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 711
|
||||
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct from C-standard layout to Unwound layout
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 1
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
// @1
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// main
|
||||
main: {
|
||||
.label to_x = 3
|
||||
.label to_y = 4
|
||||
.label j = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuxx=vbuc1
|
||||
tax
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
// main::@1
|
||||
__b1:
|
||||
// to = letter_c[i].to
|
||||
// [6] (byte~) main::$6 ← (byte) main::i#2 << (byte) 2 -- vbuaa=vbuxx_rol_2
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$6 + (byte) main::i#2 -- vbuyy=vbuaa_plus_vbuxx
|
||||
stx.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
tay
|
||||
// [8] (byte) main::to_x#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) -- vbuz1=pbuc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
// [9] (byte) main::to_y#0 ← *((byte*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) -- vbuz1=pbuc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
// SCREEN[j++] = to.x
|
||||
// [10] *((const byte*) SCREEN + (byte) main::j#3) ← (byte) main::to_x#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z to_x
|
||||
ldy.z j
|
||||
sta SCREEN,y
|
||||
// SCREEN[j++] = to.x;
|
||||
// [11] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuyy=_inc_vbuz1
|
||||
iny
|
||||
// SCREEN[j++] = to.y
|
||||
// [12] *((const byte*) SCREEN + (byte) main::j#1) ← (byte) main::to_y#0 -- pbuc1_derefidx_vbuyy=vbuz1
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
// SCREEN[j++] = to.y;
|
||||
// [13] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuyy
|
||||
iny
|
||||
sty.z j
|
||||
// for( byte i: 0..2)
|
||||
// [14] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [15] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #3
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO, 'a', 'b', 0, 0, SPLINE_TO, 'c', 'd', $67, $a9, SPLINE_TO, 'e', 'f', $4b, $c3
|
||||
|
41
src/test/ref/struct-37.sym
Normal file
41
src/test/ref/struct-37.sym
Normal file
@ -0,0 +1,41 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y = (byte) 1
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(byte) SplineVector16::x
|
||||
(byte) SplineVector16::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (byte) 'a', y: (byte) 'b' }, via: { x: (byte) 0, y: (byte) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (byte) 'c', y: (byte) 'd' }, via: { x: (byte) $67, y: (byte) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (byte) 'e', y: (byte) 'f' }, via: { x: (byte) $4b, y: (byte) $c3 } } }
|
||||
(void()) main()
|
||||
(byte~) main::$1 reg byte y 16.5
|
||||
(byte~) main::$6 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 4.888888888888889
|
||||
(byte) main::j
|
||||
(byte) main::j#1 reg byte y 16.5
|
||||
(byte) main::j#2 j zp[1]:2 7.333333333333333
|
||||
(byte) main::j#3 j zp[1]:2 5.5
|
||||
(byte) main::to_x
|
||||
(byte) main::to_x#0 to_x zp[1]:3 11.0
|
||||
(byte) main::to_y
|
||||
(byte) main::to_y#0 to_y zp[1]:4 7.333333333333333
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp[1]:2 [ main::j#3 main::j#2 ]
|
||||
reg byte a [ main::$6 ]
|
||||
reg byte y [ main::$1 ]
|
||||
zp[1]:3 [ main::to_x#0 ]
|
||||
zp[1]:4 [ main::to_y#0 ]
|
||||
reg byte y [ main::j#1 ]
|
61
src/test/ref/struct-38.asm
Normal file
61
src/test/ref/struct-38.asm
Normal file
@ -0,0 +1,61 @@
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to Unwound layout
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 2
|
||||
main: {
|
||||
.label to_x = 3
|
||||
.label to_y = 5
|
||||
.label j = 2
|
||||
lda #0
|
||||
sta.z j
|
||||
tax
|
||||
__b1:
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
stx.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
tay
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,y
|
||||
sta.z to_x+1
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,y
|
||||
sta.z to_y+1
|
||||
lda.z j
|
||||
asl
|
||||
tay
|
||||
lda.z to_x
|
||||
sta SCREEN,y
|
||||
lda.z to_x+1
|
||||
sta SCREEN+1,y
|
||||
inc.z j
|
||||
lda.z j
|
||||
asl
|
||||
tay
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
lda.z to_y+1
|
||||
sta SCREEN+1,y
|
||||
inc.z j
|
||||
inx
|
||||
cpx #3
|
||||
bne __b1
|
||||
rts
|
||||
}
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
33
src/test/ref/struct-38.cfg
Normal file
33
src/test/ref/struct-38.cfg
Normal file
@ -0,0 +1,33 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::j#3 ← phi( main/(byte) 0 main::@1/(byte) main::j#2 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3
|
||||
[7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2
|
||||
[8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1)
|
||||
[9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1)
|
||||
[10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1
|
||||
[11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0
|
||||
[12] (byte) main::j#1 ← ++ (byte) main::j#3
|
||||
[13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1
|
||||
[14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0
|
||||
[15] (byte) main::j#2 ← ++ (byte) main::j#1
|
||||
[16] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[17] if((byte) main::i#1!=(byte) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[18] return
|
||||
to:@return
|
730
src/test/ref/struct-38.log
Normal file
730
src/test/ref/struct-38.log
Normal file
@ -0,0 +1,730 @@
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) main::i)
|
||||
Fixing pointer array-indexing *((const signed word*) SCREEN + (byte) main::j)
|
||||
Fixing pointer array-indexing *((const signed word*) SCREEN + (byte) main::j)
|
||||
Created struct value member variable (signed word) main::to_x
|
||||
Created struct value member variable (signed word) main::to_y
|
||||
Converted struct value to member variables (struct SplineVector16) main::to
|
||||
Adding struct value member variable copy (signed word) main::to_x ← *((signed word*~) main::$5 + (byte~) main::$1)
|
||||
Adding struct value member variable copy (signed word) main::to_y ← *((signed word*~) main::$7 + (byte~) main::$1)
|
||||
Replacing struct member reference (struct SplineVector16) main::to.x with member unwinding reference (signed word) main::to_x
|
||||
Replacing struct member reference (struct SplineVector16) main::to.y with member unwinding reference (signed word) main::to_y
|
||||
Culled Empty Block (label) main::@2
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
(byte) main::j#0 ← (byte) 0
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::j#3 ← phi( main/(byte) main::j#0 main::@1/(byte) main::j#2 )
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
(byte~) main::$1 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
(signed word*~) main::$5 ← (signed word*)(signed word*~) main::$4 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
(signed word) main::to_x#0 ← *((signed word*~) main::$5 + (byte~) main::$1)
|
||||
(signed word*~) main::$4 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(signed word*~) main::$7 ← (signed word*)(signed word*~) main::$6 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
(signed word) main::to_y#0 ← *((signed word*~) main::$7 + (byte~) main::$1)
|
||||
(signed word*~) main::$6 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
(byte~) main::$2 ← (byte) main::j#3 * (const byte) SIZEOF_SIGNED_WORD
|
||||
*((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0
|
||||
(byte) main::j#1 ← ++ (byte) main::j#3
|
||||
(byte~) main::$3 ← (byte) main::j#1 * (const byte) SIZEOF_SIGNED_WORD
|
||||
*((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0
|
||||
(byte) main::j#2 ← ++ (byte) main::j#1
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,2)
|
||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,2)
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_X = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y = (byte) 2
|
||||
(const signed word*) SCREEN = (signed word*)(number) $400
|
||||
(const byte) SIZEOF_SIGNED_WORD = (byte) 2
|
||||
(const byte) SIZEOF_STRUCT_SEGMENT = (byte) 9
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(signed word) SplineVector16::x
|
||||
(signed word) SplineVector16::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (signed word)(byte) 'a', y: (signed word)(byte) 'b' }, via: { x: (signed word) 0, y: (signed word) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'c', y: (signed word)(byte) 'd' }, via: { x: (signed word) $67, y: (signed word) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'e', y: (signed word)(byte) 'f' }, via: { x: (signed word) $4b, y: (signed word) $c3 } } }
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(byte~) main::$1
|
||||
(byte~) main::$2
|
||||
(byte~) main::$3
|
||||
(signed word*~) main::$4
|
||||
(signed word*~) main::$5
|
||||
(signed word*~) main::$6
|
||||
(signed word*~) main::$7
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
(byte) main::j
|
||||
(byte) main::j#0
|
||||
(byte) main::j#1
|
||||
(byte) main::j#2
|
||||
(byte) main::j#3
|
||||
(signed word) main::to_x
|
||||
(signed word) main::to_x#0
|
||||
(signed word) main::to_y
|
||||
(signed word) main::to_y#0
|
||||
|
||||
Simplifying constant pointer cast (signed word*) 1024
|
||||
Simplifying constant integer cast (signed word*~) main::$4
|
||||
Simplifying constant integer cast (signed word*~) main::$6
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Simple Condition (bool~) main::$0 [18] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant right-side identified [6] (signed word*~) main::$4 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant right-side identified [9] (signed word*~) main::$6 ← (signed word*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::j#0 = 0
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Constant (const signed word*) main::$4 = (signed word*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant (const signed word*) main::$6 = (signed word*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [16] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [18] if(main::i#1!=rangelast(0,2)) goto main::@1 to (number) 3
|
||||
Simplifying expression containing zero main::$4 in [4] (signed word*~) main::$5 ← (const signed word*) main::$4 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) OFFSET_STRUCT_SPLINEVECTOR16_X
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding number conversion cast (unumber) 3 in if((byte) main::i#1!=(number) 3) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant integer cast 3
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 3
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Constant right-side identified [4] (signed word*~) main::$7 ← (const signed word*) main::$6 + (const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const signed word*) main::$5 = main::$4
|
||||
Constant (const signed word*) main::$7 = main::$6+OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Rewriting multiplication to use shift and addition[1] (byte~) main::$1 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
Rewriting multiplication to use shift [4] (byte~) main::$2 ← (byte) main::j#3 * (const byte) SIZEOF_SIGNED_WORD
|
||||
Rewriting multiplication to use shift [7] (byte~) main::$3 ← (byte) main::j#1 * (const byte) SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization Pass2MultiplyToShiftRewriting
|
||||
Inlining constant with var siblings (const byte) main::j#0
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Constant inlined main::$5 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::i#0 = (byte) 0
|
||||
Constant inlined main::$6 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::$4 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::j#0 = (byte) 0
|
||||
Constant inlined main::$7 = (signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Alias (byte~) main::$1 = (byte~) main::$9
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Eliminating unused constant (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
Eliminating unused constant (const byte) SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced [20] main::i#3 ← main::i#1
|
||||
Coalesced [21] main::j#4 ← main::j#2
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) @2
|
||||
Culled Empty Block (label) main::@3
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::j#3 ← phi( main/(byte) 0 main::@1/(byte) main::j#2 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3
|
||||
[7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2
|
||||
[8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1)
|
||||
[9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1)
|
||||
[10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1
|
||||
[11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0
|
||||
[12] (byte) main::j#1 ← ++ (byte) main::j#3
|
||||
[13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1
|
||||
[14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0
|
||||
[15] (byte) main::j#2 ← ++ (byte) main::j#1
|
||||
[16] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[17] if((byte) main::i#1!=(byte) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(signed word) SplineVector16::x
|
||||
(signed word) SplineVector16::y
|
||||
(void()) main()
|
||||
(byte~) main::$1 16.5
|
||||
(byte~) main::$2 22.0
|
||||
(byte~) main::$3 22.0
|
||||
(byte~) main::$8 22.0
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 4.0
|
||||
(byte) main::j
|
||||
(byte) main::j#1 11.0
|
||||
(byte) main::j#2 7.333333333333333
|
||||
(byte) main::j#3 4.714285714285714
|
||||
(signed word) main::to_x
|
||||
(signed word) main::to_x#0 7.333333333333333
|
||||
(signed word) main::to_y
|
||||
(signed word) main::to_y#0 4.4
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::j#3 main::j#2 ]
|
||||
Added variable main::$8 to live range equivalence class [ main::$8 ]
|
||||
Added variable main::$1 to live range equivalence class [ main::$1 ]
|
||||
Added variable main::to_x#0 to live range equivalence class [ main::to_x#0 ]
|
||||
Added variable main::to_y#0 to live range equivalence class [ main::to_y#0 ]
|
||||
Added variable main::$2 to live range equivalence class [ main::$2 ]
|
||||
Added variable main::j#1 to live range equivalence class [ main::j#1 ]
|
||||
Added variable main::$3 to live range equivalence class [ main::$3 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::j#3 main::j#2 ]
|
||||
[ main::$8 ]
|
||||
[ main::$1 ]
|
||||
[ main::to_x#0 ]
|
||||
[ main::to_y#0 ]
|
||||
[ main::$2 ]
|
||||
[ main::j#1 ]
|
||||
[ main::$3 ]
|
||||
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Allocated zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Allocated zp[1]:4 [ main::$8 ]
|
||||
Allocated zp[1]:5 [ main::$1 ]
|
||||
Allocated zp[2]:6 [ main::to_x#0 ]
|
||||
Allocated zp[2]:8 [ main::to_y#0 ]
|
||||
Allocated zp[1]:10 [ main::$2 ]
|
||||
Allocated zp[1]:11 [ main::j#1 ]
|
||||
Allocated zp[1]:12 [ main::$3 ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to Unwound layout
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 2
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label __1 = 5
|
||||
.label __2 = $a
|
||||
.label __3 = $c
|
||||
.label to_x = 6
|
||||
.label to_y = 8
|
||||
.label j = $b
|
||||
.label j_1 = 3
|
||||
.label i = 2
|
||||
.label __8 = 4
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j_1
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3 -- vbuz1=vbuz2_rol_3
|
||||
lda.z i
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta.z __8
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z __8
|
||||
clc
|
||||
adc.z i
|
||||
sta.z __1
|
||||
// [8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
ldy.z __1
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,y
|
||||
sta.z to_x+1
|
||||
// [9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) -- vwsz1=pwsc1_derefidx_vbuz2
|
||||
ldy.z __1
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,y
|
||||
sta.z to_y+1
|
||||
// [10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 -- vbuz1=vbuz2_rol_1
|
||||
lda.z j_1
|
||||
asl
|
||||
sta.z __2
|
||||
// [11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0 -- pwsc1_derefidx_vbuz1=vwsz2
|
||||
ldy.z __2
|
||||
lda.z to_x
|
||||
sta SCREEN,y
|
||||
lda.z to_x+1
|
||||
sta SCREEN+1,y
|
||||
// [12] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuz1=_inc_vbuz2
|
||||
ldy.z j_1
|
||||
iny
|
||||
sty.z j
|
||||
// [13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 -- vbuz1=vbuz2_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
sta.z __3
|
||||
// [14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0 -- pwsc1_derefidx_vbuz1=vwsz2
|
||||
ldy.z __3
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
lda.z to_y+1
|
||||
sta SCREEN+1,y
|
||||
// [15] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuz2
|
||||
ldy.z j
|
||||
iny
|
||||
sty.z j_1
|
||||
// [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [17] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #3
|
||||
cmp.z i
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3 [ main::i#2 main::j#3 main::$8 ] ( main:2 [ main::i#2 main::j#3 main::$8 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Statement [7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2 [ main::i#2 main::j#3 main::$1 ] ( main:2 [ main::i#2 main::j#3 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) [ main::i#2 main::j#3 main::$1 main::to_x#0 ] ( main:2 [ main::i#2 main::j#3 main::$1 main::to_x#0 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:5 [ main::$1 ]
|
||||
Statement [9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 ] ( main:2 [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 main::$2 ] ( main:2 [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0 [ main::i#2 main::j#3 main::to_y#0 ] ( main:2 [ main::i#2 main::j#3 main::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 [ main::i#2 main::to_y#0 main::j#1 main::$3 ] ( main:2 [ main::i#2 main::to_y#0 main::j#1 main::$3 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:11 [ main::j#1 ]
|
||||
Statement [14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0 [ main::i#2 main::j#1 ] ( main:2 [ main::i#2 main::j#1 ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3 [ main::i#2 main::j#3 main::$8 ] ( main:2 [ main::i#2 main::j#3 main::$8 ] ) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2 [ main::i#2 main::j#3 main::$1 ] ( main:2 [ main::i#2 main::j#3 main::$1 ] ) always clobbers reg byte a
|
||||
Statement [8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) [ main::i#2 main::j#3 main::$1 main::to_x#0 ] ( main:2 [ main::i#2 main::j#3 main::$1 main::to_x#0 ] ) always clobbers reg byte a
|
||||
Statement [9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 ] ( main:2 [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 main::$2 ] ( main:2 [ main::i#2 main::j#3 main::to_x#0 main::to_y#0 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0 [ main::i#2 main::j#3 main::to_y#0 ] ( main:2 [ main::i#2 main::j#3 main::to_y#0 ] ) always clobbers reg byte a
|
||||
Statement [13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 [ main::i#2 main::to_y#0 main::j#1 main::$3 ] ( main:2 [ main::i#2 main::to_y#0 main::j#1 main::$3 ] ) always clobbers reg byte a
|
||||
Statement [14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0 [ main::i#2 main::j#1 ] ( main:2 [ main::i#2 main::j#1 ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:3 [ main::j#3 main::j#2 ] : zp[1]:3 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:4 [ main::$8 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ main::$1 ] : zp[1]:5 , reg byte x , reg byte y ,
|
||||
Potential registers zp[2]:6 [ main::to_x#0 ] : zp[2]:6 ,
|
||||
Potential registers zp[2]:8 [ main::to_y#0 ] : zp[2]:8 ,
|
||||
Potential registers zp[1]:10 [ main::$2 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:11 [ main::j#1 ] : zp[1]:11 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:12 [ main::$3 ] : zp[1]:12 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 22: zp[1]:4 [ main::$8 ] 22: zp[1]:10 [ main::$2 ] 22: zp[1]:12 [ main::$3 ] 20.5: zp[1]:2 [ main::i#2 main::i#1 ] 16.5: zp[1]:5 [ main::$1 ] 12.05: zp[1]:3 [ main::j#3 main::j#2 ] 11: zp[1]:11 [ main::j#1 ] 7.33: zp[2]:6 [ main::to_x#0 ] 4.4: zp[2]:8 [ main::to_y#0 ]
|
||||
Uplift Scope [SplineVector16]
|
||||
Uplift Scope [Segment]
|
||||
Uplift Scope [Segment::SegmentType]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 1413 combination reg byte a [ main::$8 ] reg byte a [ main::$2 ] reg byte a [ main::$3 ] reg byte x [ main::i#2 main::i#1 ] zp[1]:5 [ main::$1 ] zp[1]:3 [ main::j#3 main::j#2 ] zp[1]:11 [ main::j#1 ] zp[2]:6 [ main::to_x#0 ] zp[2]:8 [ main::to_y#0 ]
|
||||
Limited combination testing to 100 combinations of 5184 possible.
|
||||
Uplifting [SplineVector16] best 1413 combination
|
||||
Uplifting [Segment] best 1413 combination
|
||||
Uplifting [Segment::SegmentType] best 1413 combination
|
||||
Uplifting [] best 1413 combination
|
||||
Attempting to uplift remaining variables inzp[1]:5 [ main::$1 ]
|
||||
Uplifting [main] best 1343 combination reg byte y [ main::$1 ]
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Uplifting [main] best 1343 combination zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Attempting to uplift remaining variables inzp[1]:11 [ main::j#1 ]
|
||||
Uplifting [main] best 1343 combination zp[1]:11 [ main::j#1 ]
|
||||
Coalescing zero page register [ zp[1]:3 [ main::j#3 main::j#2 ] ] with [ zp[1]:11 [ main::j#1 ] ] - score: 2
|
||||
Allocated (was zp[1]:3) zp[1]:2 [ main::j#3 main::j#2 main::j#1 ]
|
||||
Allocated (was zp[2]:6) zp[2]:3 [ main::to_x#0 ]
|
||||
Allocated (was zp[2]:8) zp[2]:5 [ main::to_y#0 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to Unwound layout
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 2
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label to_x = 3
|
||||
.label to_y = 5
|
||||
.label j = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3 -- vbuaa=vbuxx_rol_3
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2 -- vbuyy=vbuaa_plus_vbuxx
|
||||
stx.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
tay
|
||||
// [8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) -- vwsz1=pwsc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,y
|
||||
sta.z to_x+1
|
||||
// [9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) -- vwsz1=pwsc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,y
|
||||
sta.z to_y+1
|
||||
// [10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 -- vbuaa=vbuz1_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
// [11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0 -- pwsc1_derefidx_vbuaa=vwsz1
|
||||
tay
|
||||
lda.z to_x
|
||||
sta SCREEN,y
|
||||
lda.z to_x+1
|
||||
sta SCREEN+1,y
|
||||
// [12] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuz1=_inc_vbuz1
|
||||
inc.z j
|
||||
// [13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 -- vbuaa=vbuz1_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
// [14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0 -- pwsc1_derefidx_vbuaa=vwsz1
|
||||
tay
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
lda.z to_y+1
|
||||
sta SCREEN+1,y
|
||||
// [15] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuz1
|
||||
inc.z j
|
||||
// [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [17] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #3
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __bend
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing instruction ldx #0 with TAX
|
||||
Replacing label __bbegin with __b1
|
||||
Replacing label __b1_from___b1 with __b1
|
||||
Removing instruction __bbegin:
|
||||
Removing instruction __b1_from___bbegin:
|
||||
Removing instruction main_from___b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Removing instruction __b1_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction jmp __b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __b1:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y = (byte) 2
|
||||
(const signed word*) SCREEN = (signed word*) 1024
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(signed word) SplineVector16::x
|
||||
(signed word) SplineVector16::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (signed word)(byte) 'a', y: (signed word)(byte) 'b' }, via: { x: (signed word) 0, y: (signed word) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'c', y: (signed word)(byte) 'd' }, via: { x: (signed word) $67, y: (signed word) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'e', y: (signed word)(byte) 'f' }, via: { x: (signed word) $4b, y: (signed word) $c3 } } }
|
||||
(void()) main()
|
||||
(byte~) main::$1 reg byte y 16.5
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(byte~) main::$3 reg byte a 22.0
|
||||
(byte~) main::$8 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 4.0
|
||||
(byte) main::j
|
||||
(byte) main::j#1 j zp[1]:2 11.0
|
||||
(byte) main::j#2 j zp[1]:2 7.333333333333333
|
||||
(byte) main::j#3 j zp[1]:2 4.714285714285714
|
||||
(signed word) main::to_x
|
||||
(signed word) main::to_x#0 to_x zp[2]:3 7.333333333333333
|
||||
(signed word) main::to_y
|
||||
(signed word) main::to_y#0 to_y zp[2]:5 4.4
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp[1]:2 [ main::j#3 main::j#2 main::j#1 ]
|
||||
reg byte a [ main::$8 ]
|
||||
reg byte y [ main::$1 ]
|
||||
zp[2]:3 [ main::to_x#0 ]
|
||||
zp[2]:5 [ main::to_y#0 ]
|
||||
reg byte a [ main::$2 ]
|
||||
reg byte a [ main::$3 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 1181
|
||||
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to Unwound layout
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_SPLINEVECTOR16_Y = 2
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
// @1
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// main
|
||||
main: {
|
||||
.label to_x = 3
|
||||
.label to_y = 5
|
||||
.label j = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuxx=vbuc1
|
||||
tax
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
// main::@1
|
||||
__b1:
|
||||
// to = letter_c[i].to
|
||||
// [6] (byte~) main::$8 ← (byte) main::i#2 << (byte) 3 -- vbuaa=vbuxx_rol_3
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$8 + (byte) main::i#2 -- vbuyy=vbuaa_plus_vbuxx
|
||||
stx.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
tay
|
||||
// [8] (signed word) main::to_x#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1) -- vwsz1=pwsc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,y
|
||||
sta.z to_x
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+1,y
|
||||
sta.z to_x+1
|
||||
// [9] (signed word) main::to_y#0 ← *((signed word*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO+(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y + (byte~) main::$1) -- vwsz1=pwsc1_derefidx_vbuyy
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y,y
|
||||
sta.z to_y
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO+OFFSET_STRUCT_SPLINEVECTOR16_Y+1,y
|
||||
sta.z to_y+1
|
||||
// SCREEN[j++] = to.x
|
||||
// [10] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 -- vbuaa=vbuz1_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
// [11] *((const signed word*) SCREEN + (byte~) main::$2) ← (signed word) main::to_x#0 -- pwsc1_derefidx_vbuaa=vwsz1
|
||||
tay
|
||||
lda.z to_x
|
||||
sta SCREEN,y
|
||||
lda.z to_x+1
|
||||
sta SCREEN+1,y
|
||||
// SCREEN[j++] = to.x;
|
||||
// [12] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuz1=_inc_vbuz1
|
||||
inc.z j
|
||||
// SCREEN[j++] = to.y
|
||||
// [13] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 -- vbuaa=vbuz1_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
// [14] *((const signed word*) SCREEN + (byte~) main::$3) ← (signed word) main::to_y#0 -- pwsc1_derefidx_vbuaa=vwsz1
|
||||
tay
|
||||
lda.z to_y
|
||||
sta SCREEN,y
|
||||
lda.z to_y+1
|
||||
sta SCREEN+1,y
|
||||
// SCREEN[j++] = to.y;
|
||||
// [15] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuz1
|
||||
inc.z j
|
||||
// for( byte i: 0..2)
|
||||
// [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [17] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #3
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
||||
|
44
src/test/ref/struct-38.sym
Normal file
44
src/test/ref/struct-38.sym
Normal file
@ -0,0 +1,44 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_SPLINEVECTOR16_Y = (byte) 2
|
||||
(const signed word*) SCREEN = (signed word*) 1024
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct SplineVector16) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct SplineVector16) Segment::via
|
||||
(signed word) SplineVector16::x
|
||||
(signed word) SplineVector16::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (signed word)(byte) 'a', y: (signed word)(byte) 'b' }, via: { x: (signed word) 0, y: (signed word) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'c', y: (signed word)(byte) 'd' }, via: { x: (signed word) $67, y: (signed word) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'e', y: (signed word)(byte) 'f' }, via: { x: (signed word) $4b, y: (signed word) $c3 } } }
|
||||
(void()) main()
|
||||
(byte~) main::$1 reg byte y 16.5
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(byte~) main::$3 reg byte a 22.0
|
||||
(byte~) main::$8 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 4.0
|
||||
(byte) main::j
|
||||
(byte) main::j#1 j zp[1]:2 11.0
|
||||
(byte) main::j#2 j zp[1]:2 7.333333333333333
|
||||
(byte) main::j#3 j zp[1]:2 4.714285714285714
|
||||
(signed word) main::to_x
|
||||
(signed word) main::to_x#0 to_x zp[2]:3 7.333333333333333
|
||||
(signed word) main::to_y
|
||||
(signed word) main::to_y#0 to_y zp[2]:5 4.4
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp[1]:2 [ main::j#3 main::j#2 main::j#1 ]
|
||||
reg byte a [ main::$8 ]
|
||||
reg byte y [ main::$1 ]
|
||||
zp[2]:3 [ main::to_x#0 ]
|
||||
zp[2]:5 [ main::to_y#0 ]
|
||||
reg byte a [ main::$2 ]
|
||||
reg byte a [ main::$3 ]
|
64
src/test/ref/struct-39.asm
Normal file
64
src/test/ref/struct-39.asm
Normal file
@ -0,0 +1,64 @@
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to C-standard layout (expecting a memcpy)
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_VECTOR_Y = 2
|
||||
.const SIZEOF_STRUCT_VECTOR = 4
|
||||
main: {
|
||||
.label to = 4
|
||||
.label j = 3
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta.z j
|
||||
sta.z i
|
||||
__b1:
|
||||
lda.z i
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc.z i
|
||||
tax
|
||||
ldy #0
|
||||
!:
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,x
|
||||
sta to,y
|
||||
inx
|
||||
iny
|
||||
cpy #SIZEOF_STRUCT_VECTOR
|
||||
bne !-
|
||||
lda.z j
|
||||
asl
|
||||
tay
|
||||
lda.z to
|
||||
sta SCREEN,y
|
||||
lda.z to+1
|
||||
sta SCREEN+1,y
|
||||
ldx.z j
|
||||
inx
|
||||
txa
|
||||
asl
|
||||
tay
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y
|
||||
sta SCREEN,y
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y+1
|
||||
sta SCREEN+1,y
|
||||
inx
|
||||
stx.z j
|
||||
inc.z i
|
||||
lda #3
|
||||
cmp.z i
|
||||
bne __b1
|
||||
rts
|
||||
}
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
32
src/test/ref/struct-39.cfg
Normal file
32
src/test/ref/struct-39.cfg
Normal file
@ -0,0 +1,32 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::j#3 ← phi( main/(byte) 0 main::@1/(byte) main::j#2 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3
|
||||
[7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2
|
||||
[8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
|
||||
[9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1
|
||||
[10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to)
|
||||
[11] (byte) main::j#1 ← ++ (byte) main::j#3
|
||||
[12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1
|
||||
[13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y)
|
||||
[14] (byte) main::j#2 ← ++ (byte) main::j#1
|
||||
[15] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[16] if((byte) main::i#1!=(byte) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[17] return
|
||||
to:@return
|
700
src/test/ref/struct-39.log
Normal file
700
src/test/ref/struct-39.log
Normal file
@ -0,0 +1,700 @@
|
||||
Fixing pointer array-indexing *((const struct Segment*) letter_c + (byte) main::i)
|
||||
Fixing pointer array-indexing *((const signed word*) SCREEN + (byte) main::j)
|
||||
Fixing pointer array-indexing *((const signed word*) SCREEN + (byte) main::j)
|
||||
Adding struct value member variable copy *(&(struct Vector) main::to) ← *((struct Vector*~) main::$4 + (byte~) main::$1)
|
||||
Replacing struct member reference (struct Vector) main::to.x with member unwinding reference *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_X)
|
||||
Replacing struct member reference (struct Vector) main::to.y with member unwinding reference *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y)
|
||||
Adding struct value member variable copy *(&(struct Vector) main::to) ← memcpy(*((struct Vector*~) main::$4 + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
|
||||
Culled Empty Block (label) main::@2
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
(byte) main::j#0 ← (byte) 0
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::j#3 ← phi( main/(byte) main::j#0 main::@1/(byte) main::j#2 )
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
(byte~) main::$1 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
(struct Vector*~) main::$4 ← (struct Vector*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
*(&(struct Vector) main::to) ← memcpy(*((struct Vector*~) main::$4 + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
|
||||
(byte~) main::$2 ← (byte) main::j#3 * (const byte) SIZEOF_SIGNED_WORD
|
||||
*((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_X)
|
||||
(byte) main::j#1 ← ++ (byte) main::j#3
|
||||
(byte~) main::$3 ← (byte) main::j#1 * (const byte) SIZEOF_SIGNED_WORD
|
||||
*((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y)
|
||||
(byte) main::j#2 ← ++ (byte) main::j#1
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,2)
|
||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,2)
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_VECTOR_X = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_VECTOR_Y = (byte) 2
|
||||
(const signed word*) SCREEN = (signed word*)(number) $400
|
||||
(const byte) SIZEOF_SIGNED_WORD = (byte) 2
|
||||
(const byte) SIZEOF_STRUCT_SEGMENT = (byte) 9
|
||||
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct Vector) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct Vector) Segment::via
|
||||
(signed word) Vector::x
|
||||
(signed word) Vector::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (signed word)(byte) 'a', y: (signed word)(byte) 'b' }, via: { x: (signed word) 0, y: (signed word) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'c', y: (signed word)(byte) 'd' }, via: { x: (signed word) $67, y: (signed word) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'e', y: (signed word)(byte) 'f' }, via: { x: (signed word) $4b, y: (signed word) $c3 } } }
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(byte~) main::$1
|
||||
(byte~) main::$2
|
||||
(byte~) main::$3
|
||||
(struct Vector*~) main::$4
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
(byte) main::j
|
||||
(byte) main::j#0
|
||||
(byte) main::j#1
|
||||
(byte) main::j#2
|
||||
(byte) main::j#3
|
||||
(struct Vector) main::to loadstore
|
||||
|
||||
Simplifying constant pointer cast (signed word*) 1024
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Simple Condition (bool~) main::$0 [14] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant right-side identified [4] (struct Vector*~) main::$4 ← (struct Vector*)(const struct Segment*) letter_c + (const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::j#0 = 0
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Constant (const struct Vector*) main::$4 = (struct Vector*)letter_c+OFFSET_STRUCT_SEGMENT_TO
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [12] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [14] if(main::i#1!=rangelast(0,2)) goto main::@1 to (number) 3
|
||||
Simplifying expression containing zero (signed word*)&main::to in [7] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_X)
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) OFFSET_STRUCT_VECTOR_X
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding number conversion cast (unumber) 3 in if((byte) main::i#1!=(number) 3) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant integer cast 3
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 3
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Rewriting multiplication to use shift and addition[1] (byte~) main::$1 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
Rewriting multiplication to use shift [3] (byte~) main::$2 ← (byte) main::j#3 * (const byte) SIZEOF_SIGNED_WORD
|
||||
Rewriting multiplication to use shift [6] (byte~) main::$3 ← (byte) main::j#1 * (const byte) SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization Pass2MultiplyToShiftRewriting
|
||||
Inlining constant with var siblings (const byte) main::j#0
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Constant inlined main::i#0 = (byte) 0
|
||||
Constant inlined main::$4 = (struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO
|
||||
Constant inlined main::j#0 = (byte) 0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Alias (byte~) main::$1 = (byte~) main::$6
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Eliminating unused constant (const byte) SIZEOF_STRUCT_SEGMENT
|
||||
Eliminating unused constant (const byte) SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced [19] main::i#3 ← main::i#1
|
||||
Coalesced [20] main::j#4 ← main::j#2
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) @2
|
||||
Culled Empty Block (label) main::@3
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::j#3 ← phi( main/(byte) 0 main::@1/(byte) main::j#2 )
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3
|
||||
[7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2
|
||||
[8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
|
||||
[9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1
|
||||
[10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to)
|
||||
[11] (byte) main::j#1 ← ++ (byte) main::j#3
|
||||
[12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1
|
||||
[13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y)
|
||||
[14] (byte) main::j#2 ← ++ (byte) main::j#1
|
||||
[15] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[16] if((byte) main::i#1!=(byte) 3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[17] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(struct Vector) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct Vector) Segment::via
|
||||
(signed word) Vector::x
|
||||
(signed word) Vector::y
|
||||
(void()) main()
|
||||
(byte~) main::$1 11.0
|
||||
(byte~) main::$2 22.0
|
||||
(byte~) main::$3 22.0
|
||||
(byte~) main::$5 22.0
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 4.4
|
||||
(byte) main::j
|
||||
(byte) main::j#1 11.0
|
||||
(byte) main::j#2 7.333333333333333
|
||||
(byte) main::j#3 5.5
|
||||
(struct Vector) main::to loadstore
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::j#3 main::j#2 ]
|
||||
Added variable main::$5 to live range equivalence class [ main::$5 ]
|
||||
Added variable main::$1 to live range equivalence class [ main::$1 ]
|
||||
Added variable main::$2 to live range equivalence class [ main::$2 ]
|
||||
Added variable main::j#1 to live range equivalence class [ main::j#1 ]
|
||||
Added variable main::$3 to live range equivalence class [ main::$3 ]
|
||||
Added variable main::to to live range equivalence class [ main::to ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::j#3 main::j#2 ]
|
||||
[ main::$5 ]
|
||||
[ main::$1 ]
|
||||
[ main::$2 ]
|
||||
[ main::j#1 ]
|
||||
[ main::$3 ]
|
||||
[ main::to ]
|
||||
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Allocated zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Allocated zp[1]:4 [ main::$5 ]
|
||||
Allocated zp[1]:5 [ main::$1 ]
|
||||
Allocated zp[1]:6 [ main::$2 ]
|
||||
Allocated zp[1]:7 [ main::j#1 ]
|
||||
Allocated zp[1]:8 [ main::$3 ]
|
||||
Allocated zp[4]:9 [ main::to ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to C-standard layout (expecting a memcpy)
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_VECTOR_Y = 2
|
||||
.const SIZEOF_STRUCT_VECTOR = 4
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label to = 9
|
||||
.label __1 = 5
|
||||
.label __2 = 6
|
||||
.label __3 = 8
|
||||
.label j = 7
|
||||
.label j_1 = 3
|
||||
.label i = 2
|
||||
.label __5 = 4
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j_1
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3 -- vbuz1=vbuz2_rol_3
|
||||
lda.z i
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta.z __5
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z __5
|
||||
clc
|
||||
adc.z i
|
||||
sta.z __1
|
||||
// [8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=pssc2_derefidx_vbuz1_memcpy_vbuc3
|
||||
ldx.z __1
|
||||
ldy #0
|
||||
!:
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,x
|
||||
sta to,y
|
||||
inx
|
||||
iny
|
||||
cpy #SIZEOF_STRUCT_VECTOR
|
||||
bne !-
|
||||
// [9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 -- vbuz1=vbuz2_rol_1
|
||||
lda.z j_1
|
||||
asl
|
||||
sta.z __2
|
||||
// [10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to) -- pwsc1_derefidx_vbuz1=_deref_pwsc2
|
||||
ldy.z __2
|
||||
lda.z to
|
||||
sta SCREEN,y
|
||||
lda.z to+1
|
||||
sta SCREEN+1,y
|
||||
// [11] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuz1=_inc_vbuz2
|
||||
ldy.z j_1
|
||||
iny
|
||||
sty.z j
|
||||
// [12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 -- vbuz1=vbuz2_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
sta.z __3
|
||||
// [13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y) -- pwsc1_derefidx_vbuz1=_deref_pwsc2
|
||||
ldy.z __3
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y
|
||||
sta SCREEN,y
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y+1
|
||||
sta SCREEN+1,y
|
||||
// [14] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuz2
|
||||
ldy.z j
|
||||
iny
|
||||
sty.z j_1
|
||||
// [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [16] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #3
|
||||
cmp.z i
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [17] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3 [ main::i#2 main::j#3 main::$5 main::to ] ( main:2 [ main::i#2 main::j#3 main::$5 main::to ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Statement [7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2 [ main::i#2 main::j#3 main::$1 main::to ] ( main:2 [ main::i#2 main::j#3 main::$1 main::to ] ) always clobbers reg byte a
|
||||
Statement [8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) [ main::i#2 main::j#3 main::to ] ( main:2 [ main::i#2 main::j#3 main::to ] ) always clobbers reg byte a reg byte x reg byte y
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Removing always clobbered register reg byte y as potential for zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Statement [9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 [ main::i#2 main::j#3 main::to main::$2 ] ( main:2 [ main::i#2 main::j#3 main::to main::$2 ] ) always clobbers reg byte a
|
||||
Statement [10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to) [ main::i#2 main::j#3 main::to ] ( main:2 [ main::i#2 main::j#3 main::to ] ) always clobbers reg byte a
|
||||
Statement [12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 [ main::i#2 main::to main::j#1 main::$3 ] ( main:2 [ main::i#2 main::to main::j#1 main::$3 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:7 [ main::j#1 ]
|
||||
Statement [13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y) [ main::i#2 main::to main::j#1 ] ( main:2 [ main::i#2 main::to main::j#1 ] ) always clobbers reg byte a
|
||||
Statement [16] if((byte) main::i#1!=(byte) 3) goto main::@1 [ main::i#1 main::j#2 main::to ] ( main:2 [ main::i#1 main::j#2 main::to ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3 [ main::i#2 main::j#3 main::$5 main::to ] ( main:2 [ main::i#2 main::j#3 main::$5 main::to ] ) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2 [ main::i#2 main::j#3 main::$1 main::to ] ( main:2 [ main::i#2 main::j#3 main::$1 main::to ] ) always clobbers reg byte a
|
||||
Statement [8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) [ main::i#2 main::j#3 main::to ] ( main:2 [ main::i#2 main::j#3 main::to ] ) always clobbers reg byte a reg byte x reg byte y
|
||||
Statement [9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 [ main::i#2 main::j#3 main::to main::$2 ] ( main:2 [ main::i#2 main::j#3 main::to main::$2 ] ) always clobbers reg byte a
|
||||
Statement [10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to) [ main::i#2 main::j#3 main::to ] ( main:2 [ main::i#2 main::j#3 main::to ] ) always clobbers reg byte a
|
||||
Statement [12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 [ main::i#2 main::to main::j#1 main::$3 ] ( main:2 [ main::i#2 main::to main::j#1 main::$3 ] ) always clobbers reg byte a
|
||||
Statement [13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y) [ main::i#2 main::to main::j#1 ] ( main:2 [ main::i#2 main::to main::j#1 ] ) always clobbers reg byte a
|
||||
Statement [16] if((byte) main::i#1!=(byte) 3) goto main::@1 [ main::i#1 main::j#2 main::to ] ( main:2 [ main::i#1 main::j#2 main::to ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ main::j#3 main::j#2 ] : zp[1]:3 ,
|
||||
Potential registers zp[1]:4 [ main::$5 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ main::$1 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:6 [ main::$2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:7 [ main::j#1 ] : zp[1]:7 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:8 [ main::$3 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[4]:9 [ main::to ] : zp[4]:9 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 22: zp[1]:4 [ main::$5 ] 22: zp[1]:6 [ main::$2 ] 22: zp[1]:8 [ main::$3 ] 20.9: zp[1]:2 [ main::i#2 main::i#1 ] 12.83: zp[1]:3 [ main::j#3 main::j#2 ] 11: zp[1]:5 [ main::$1 ] 11: zp[1]:7 [ main::j#1 ] 0: zp[4]:9 [ main::to ]
|
||||
Uplift Scope [Vector]
|
||||
Uplift Scope [Segment]
|
||||
Uplift Scope [Segment::SegmentType]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 1333 combination reg byte a [ main::$5 ] reg byte a [ main::$2 ] reg byte a [ main::$3 ] zp[1]:2 [ main::i#2 main::i#1 ] zp[1]:3 [ main::j#3 main::j#2 ] reg byte a [ main::$1 ] zp[1]:7 [ main::j#1 ] zp[4]:9 [ main::to ]
|
||||
Limited combination testing to 100 combinations of 768 possible.
|
||||
Uplifting [Vector] best 1333 combination
|
||||
Uplifting [Segment] best 1333 combination
|
||||
Uplifting [Segment::SegmentType] best 1333 combination
|
||||
Uplifting [] best 1333 combination
|
||||
Attempting to uplift remaining variables inzp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Uplifting [main] best 1333 combination zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Uplifting [main] best 1333 combination zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
Attempting to uplift remaining variables inzp[1]:7 [ main::j#1 ]
|
||||
Uplifting [main] best 1263 combination reg byte x [ main::j#1 ]
|
||||
Allocated (was zp[4]:9) zp[4]:4 [ main::to ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to C-standard layout (expecting a memcpy)
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_VECTOR_Y = 2
|
||||
.const SIZEOF_STRUCT_VECTOR = 4
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label to = 4
|
||||
.label j = 3
|
||||
.label i = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3 -- vbuaa=vbuz1_rol_3
|
||||
lda.z i
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuz1
|
||||
clc
|
||||
adc.z i
|
||||
// [8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=pssc2_derefidx_vbuaa_memcpy_vbuc3
|
||||
tax
|
||||
ldy #0
|
||||
!:
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,x
|
||||
sta to,y
|
||||
inx
|
||||
iny
|
||||
cpy #SIZEOF_STRUCT_VECTOR
|
||||
bne !-
|
||||
// [9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 -- vbuaa=vbuz1_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
// [10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to) -- pwsc1_derefidx_vbuaa=_deref_pwsc2
|
||||
tay
|
||||
lda.z to
|
||||
sta SCREEN,y
|
||||
lda.z to+1
|
||||
sta SCREEN+1,y
|
||||
// [11] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuxx=_inc_vbuz1
|
||||
ldx.z j
|
||||
inx
|
||||
// [12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 -- vbuaa=vbuxx_rol_1
|
||||
txa
|
||||
asl
|
||||
// [13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y) -- pwsc1_derefidx_vbuaa=_deref_pwsc2
|
||||
tay
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y
|
||||
sta SCREEN,y
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y+1
|
||||
sta SCREEN+1,y
|
||||
// [14] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuxx
|
||||
inx
|
||||
stx.z j
|
||||
// [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [16] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #3
|
||||
cmp.z i
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [17] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __bend
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction lda #0
|
||||
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||
Replacing label __bbegin with __b1
|
||||
Replacing label __b1_from___b1 with __b1
|
||||
Removing instruction __bbegin:
|
||||
Removing instruction __b1_from___bbegin:
|
||||
Removing instruction main_from___b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Removing instruction __b1_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction jmp __b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __b1:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_VECTOR_Y = (byte) 2
|
||||
(const signed word*) SCREEN = (signed word*) 1024
|
||||
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct Vector) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct Vector) Segment::via
|
||||
(signed word) Vector::x
|
||||
(signed word) Vector::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (signed word)(byte) 'a', y: (signed word)(byte) 'b' }, via: { x: (signed word) 0, y: (signed word) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'c', y: (signed word)(byte) 'd' }, via: { x: (signed word) $67, y: (signed word) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'e', y: (signed word)(byte) 'f' }, via: { x: (signed word) $4b, y: (signed word) $c3 } } }
|
||||
(void()) main()
|
||||
(byte~) main::$1 reg byte a 11.0
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(byte~) main::$3 reg byte a 22.0
|
||||
(byte~) main::$5 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 i zp[1]:2 16.5
|
||||
(byte) main::i#2 i zp[1]:2 4.4
|
||||
(byte) main::j
|
||||
(byte) main::j#1 reg byte x 11.0
|
||||
(byte) main::j#2 j zp[1]:3 7.333333333333333
|
||||
(byte) main::j#3 j zp[1]:3 5.5
|
||||
(struct Vector) main::to loadstore zp[4]:4
|
||||
|
||||
zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
reg byte a [ main::$5 ]
|
||||
reg byte a [ main::$1 ]
|
||||
reg byte a [ main::$2 ]
|
||||
reg byte x [ main::j#1 ]
|
||||
reg byte a [ main::$3 ]
|
||||
zp[4]:4 [ main::to ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 1141
|
||||
|
||||
// File Comments
|
||||
// Complex C-struct - copying a sub-struct with 2-byte members from C-standard layout to C-standard layout (expecting a memcpy)
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const MOVE_TO = 0
|
||||
.const SPLINE_TO = 1
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_SEGMENT_TO = 1
|
||||
.const OFFSET_STRUCT_VECTOR_Y = 2
|
||||
.const SIZEOF_STRUCT_VECTOR = 4
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
// @1
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// main
|
||||
main: {
|
||||
.label to = 4
|
||||
.label j = 3
|
||||
.label i = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
// [5] phi (byte) main::j#3 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z j
|
||||
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
|
||||
sta.z i
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
// [5] phi (byte) main::j#3 = (byte) main::j#2 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
// main::@1
|
||||
__b1:
|
||||
// to = letter_c[i].to
|
||||
// [6] (byte~) main::$5 ← (byte) main::i#2 << (byte) 3 -- vbuaa=vbuz1_rol_3
|
||||
lda.z i
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
// [7] (byte~) main::$1 ← (byte~) main::$5 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuz1
|
||||
clc
|
||||
adc.z i
|
||||
// [8] *(&(struct Vector) main::to) ← memcpy(*((struct Vector*)(const struct Segment*) letter_c+(const byte) OFFSET_STRUCT_SEGMENT_TO + (byte~) main::$1), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=pssc2_derefidx_vbuaa_memcpy_vbuc3
|
||||
tax
|
||||
ldy #0
|
||||
!:
|
||||
lda letter_c+OFFSET_STRUCT_SEGMENT_TO,x
|
||||
sta to,y
|
||||
inx
|
||||
iny
|
||||
cpy #SIZEOF_STRUCT_VECTOR
|
||||
bne !-
|
||||
// SCREEN[j++] = to.x
|
||||
// [9] (byte~) main::$2 ← (byte) main::j#3 << (byte) 1 -- vbuaa=vbuz1_rol_1
|
||||
lda.z j
|
||||
asl
|
||||
// [10] *((const signed word*) SCREEN + (byte~) main::$2) ← *((signed word*)&(struct Vector) main::to) -- pwsc1_derefidx_vbuaa=_deref_pwsc2
|
||||
tay
|
||||
lda.z to
|
||||
sta SCREEN,y
|
||||
lda.z to+1
|
||||
sta SCREEN+1,y
|
||||
// SCREEN[j++] = to.x;
|
||||
// [11] (byte) main::j#1 ← ++ (byte) main::j#3 -- vbuxx=_inc_vbuz1
|
||||
ldx.z j
|
||||
inx
|
||||
// SCREEN[j++] = to.y
|
||||
// [12] (byte~) main::$3 ← (byte) main::j#1 << (byte) 1 -- vbuaa=vbuxx_rol_1
|
||||
txa
|
||||
asl
|
||||
// [13] *((const signed word*) SCREEN + (byte~) main::$3) ← *((signed word*)&(struct Vector) main::to+(const byte) OFFSET_STRUCT_VECTOR_Y) -- pwsc1_derefidx_vbuaa=_deref_pwsc2
|
||||
tay
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y
|
||||
sta SCREEN,y
|
||||
lda to+OFFSET_STRUCT_VECTOR_Y+1
|
||||
sta SCREEN+1,y
|
||||
// SCREEN[j++] = to.y;
|
||||
// [14] (byte) main::j#2 ← ++ (byte) main::j#1 -- vbuz1=_inc_vbuxx
|
||||
inx
|
||||
stx.z j
|
||||
// for( byte i: 0..2)
|
||||
// [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [16] if((byte) main::i#1!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #3
|
||||
cmp.z i
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
// [17] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
// True type letter c
|
||||
letter_c: .byte MOVE_TO
|
||||
.word 'a', 'b', 0, 0
|
||||
.byte SPLINE_TO
|
||||
.word 'c', 'd', $67, $a9
|
||||
.byte SPLINE_TO
|
||||
.word 'e', 'f', $4b, $c3
|
||||
|
42
src/test/ref/struct-39.sym
Normal file
42
src/test/ref/struct-39.sym
Normal file
@ -0,0 +1,42 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) MOVE_TO = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_SEGMENT_TO = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_VECTOR_Y = (byte) 2
|
||||
(const signed word*) SCREEN = (signed word*) 1024
|
||||
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
|
||||
(const byte) SPLINE_TO = (byte) 1
|
||||
(const byte) Segment::SegmentType::LINE_TO = (byte) 2
|
||||
(const byte) Segment::SegmentType::MOVE_TO = (byte) 0
|
||||
(const byte) Segment::SegmentType::SPLINE_TO = (byte) 1
|
||||
(struct Vector) Segment::to
|
||||
(byte) Segment::type
|
||||
(struct Vector) Segment::via
|
||||
(signed word) Vector::x
|
||||
(signed word) Vector::y
|
||||
(const struct Segment*) letter_c[] = { { type: (const byte) MOVE_TO, to: { x: (signed word)(byte) 'a', y: (signed word)(byte) 'b' }, via: { x: (signed word) 0, y: (signed word) 0 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'c', y: (signed word)(byte) 'd' }, via: { x: (signed word) $67, y: (signed word) $a9 } }, { type: (const byte) SPLINE_TO, to: { x: (signed word)(byte) 'e', y: (signed word)(byte) 'f' }, via: { x: (signed word) $4b, y: (signed word) $c3 } } }
|
||||
(void()) main()
|
||||
(byte~) main::$1 reg byte a 11.0
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(byte~) main::$3 reg byte a 22.0
|
||||
(byte~) main::$5 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 i zp[1]:2 16.5
|
||||
(byte) main::i#2 i zp[1]:2 4.4
|
||||
(byte) main::j
|
||||
(byte) main::j#1 reg byte x 11.0
|
||||
(byte) main::j#2 j zp[1]:3 7.333333333333333
|
||||
(byte) main::j#3 j zp[1]:3 5.5
|
||||
(struct Vector) main::to loadstore zp[4]:4
|
||||
|
||||
zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
zp[1]:3 [ main::j#3 main::j#2 ]
|
||||
reg byte a [ main::$5 ]
|
||||
reg byte a [ main::$1 ]
|
||||
reg byte a [ main::$2 ]
|
||||
reg byte x [ main::j#1 ]
|
||||
reg byte a [ main::$3 ]
|
||||
zp[4]:4 [ main::to ]
|
Loading…
x
Reference in New Issue
Block a user