1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-17 10:30:43 +00:00

Implemented sizeof(expr). Closes #171

This commit is contained in:
jespergravgaard 2019-04-17 21:27:32 +02:00
parent 417a1d4b22
commit d55a958c70
44 changed files with 1699 additions and 537 deletions

View File

@ -252,6 +252,7 @@ public class Compiler {
optimizations.add(new Pass2ComparisonOptimization(program));
optimizations.add(new Pass2ConstantCallPointerIdentification(program));
optimizations.add(new Pass2MultiplyToShiftRewriting(program));
optimizations.add(new Pass2SizeOfSimplification(program));
pass2Execute(optimizations);
}

View File

@ -263,18 +263,18 @@ public class VariableReferenceInfos {
/**
* Get all constatns referencing another constant
* Get all constants (or symbol definitions) referencing another constant
*
* @param constRef The constant to look for
* @return All constants that reference the constant in their value
* @return All constants (or symbol definitions) that reference the constant in their value
*/
public Collection<ConstantRef> getConstRefConsts(ConstantRef constRef) {
public Collection<SymbolVariableRef> getSymbolRefConsts(ConstantRef constRef) {
Collection<ReferenceToSymbolVar> refs = symbolVarReferences.get(constRef);
LinkedHashSet<ConstantRef> constRefs = new LinkedHashSet<>();
LinkedHashSet<SymbolVariableRef> constRefs = new LinkedHashSet<>();
refs.stream()
.filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType()))
.filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInSymbol)
.forEach(referenceToSymbolVar -> constRefs.add((ConstantRef) ((ReferenceInSymbol) referenceToSymbolVar).getReferencingSymbol()));
.forEach(referenceToSymbolVar -> constRefs.add(((ReferenceInSymbol) referenceToSymbolVar).getReferencingSymbol()));
return constRefs;
}

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.model.operators;
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.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
@ -14,7 +15,7 @@ public class OperatorAddressOf extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
throw new ConstantNotLiteral("Constant not literal");
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorBitwiseNot extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left) {
public ConstantLiteral calculateLiteral(ConstantLiteral left, ProgramScope scope) {
if(left instanceof ConstantInteger) {
return new ConstantInteger(Math.abs(~((ConstantInteger) left).getInteger()));
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -15,7 +16,7 @@ public class OperatorCastBool extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0x1 & ((ConstantInteger) value).getValue());
} else if(value instanceof ConstantPointer) {

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -15,7 +16,7 @@ public class OperatorCastByte extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0xff & ((ConstantInteger) value).getValue());
} else if(value instanceof ConstantPointer) {

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -15,7 +16,7 @@ public class OperatorCastDWord extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0xffffffffL & ((ConstantInteger) value).getValue());
}

View File

@ -1,6 +1,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.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
@ -19,7 +20,7 @@ public class OperatorCastPtr extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantPointer(((ConstantInteger) value).getInteger(), elementType);
} else if(value instanceof ConstantPointer) {

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorCastSByte extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0xff & ((ConstantInteger) value).getValue());
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorCastSDWord extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0xffffffffL & ((ConstantInteger) value).getValue());
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorCastSWord extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0xffff & ((ConstantInteger) value).getValue());
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -15,7 +16,7 @@ public class OperatorCastWord extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0xffff & ((ConstantInteger) value).getValue());
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorDecrement extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
if(operand instanceof ConstantInteger ) {
return new ConstantInteger(((ConstantInteger) operand).getInteger() -1);
}

View File

@ -1,6 +1,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.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
@ -14,7 +15,7 @@ public class OperatorDeref extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
throw new CompileError("Calculation not implemented " + getOperator() + " " + operand );
}

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.operators;
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.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
@ -18,7 +19,7 @@ public class OperatorGetHigh extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
if(operand instanceof ConstantInteger) {
ConstantInteger operandInt = (ConstantInteger) operand;
if(SymbolType.isWord(operandInt.getType()) || SymbolType.isSWord(operandInt.getType())) {

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.operators;
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.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
@ -18,7 +19,7 @@ public class OperatorGetLow extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
if(operand instanceof ConstantInteger) {
ConstantInteger operandInt = (ConstantInteger) operand;
if(SymbolType.isWord(operandInt.getType()) || SymbolType.isSWord(operandInt.getType())) {

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -15,7 +16,7 @@ public class OperatorIncrement extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
if(operand instanceof ConstantInteger ) {
return new ConstantInteger(((ConstantInteger) operand).getInteger() + 1);
} else if(operand instanceof ConstantPointer) {

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantBool;
@ -14,7 +15,7 @@ public class OperatorLogicNot extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left) {
public ConstantLiteral calculateLiteral(ConstantLiteral left, ProgramScope scope) {
if(left instanceof ConstantBool) {
return new ConstantBool(!((ConstantBool) left).getBool() );
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorNeg extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
if(operand instanceof ConstantInteger) {
return new ConstantInteger(-((ConstantInteger)operand).getInteger());
}

View File

@ -1,6 +1,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.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -14,7 +15,7 @@ public class OperatorPos extends OperatorUnary {
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand) {
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
if(operand instanceof ConstantInteger) {
return new ConstantInteger(+((ConstantInteger)operand).getInteger());
}

View File

@ -0,0 +1,66 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeMulti;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantRef;
/** SizeOf operator sizeof(expr). Will be resolved into a constant as soon as the expression has been resolved enough. */
public class OperatorSizeOf extends OperatorUnary {
public OperatorSizeOf(int precedence) {
super("sizeof ", "_sizeof_", precedence);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
SymbolType type = operand.getType(scope);
return new ConstantInteger((long)type.getSizeBytes());
}
@Override
public SymbolType inferType(SymbolTypeSimple operandType) {
return SymbolType.BYTE;
}
/**
* Get the constant variable containing the size of a specific type
* @param programScope The program scope (used for finding/adding the constant).
* @param type The type to get the variable for
* @return The constant variable
*/
public static ConstantRef getSizeOfConstantVar(ProgramScope programScope, SymbolType type) {
String typeConstName = getSizeofConstantName(type);
ConstantVar typeSizeConstant = programScope.getConstant(typeConstName);
if(typeSizeConstant ==null) {
// Constant not found - create it
long typeSize = type.getSizeBytes();
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize));
programScope.add(typeSizeConstant);
}
return typeSizeConstant.getRef();
}
/**
* Get the name of the constant variable containing the size of a specific type
* @param type The type to get the variable for
* @return The name of the constant
*/
public static String getSizeofConstantName(SymbolType type) {
if(type instanceof SymbolTypeMulti) {
// Grab the first sub-type. It will be the smallest
SymbolType subType = ((SymbolTypeMulti) type).getTypes().iterator().next();
return getSizeofConstantName(subType);
} else if(type instanceof SymbolTypePointer) {
return "SIZEOF_POINTER";
} else {
return "SIZEOF_"+type.getTypeName().toUpperCase().replace(" ", "_");
}
}
}

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantLiteral;
@ -14,9 +15,10 @@ public abstract class OperatorUnary extends Operator {
/**
* Calculate the literal value of the operator applied to a constant operand
* @param operand The constant operand
* @param scope
* @return The literal value
*/
public abstract ConstantLiteral calculateLiteral(ConstantLiteral operand);
public abstract ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope);
/**
* Infer the type of the operator applied to an operand of a specific type

View File

@ -26,6 +26,7 @@ public class Operators {
public static final OperatorUnary CAST_DWORD = new OperatorCastDWord(2);
public static final OperatorUnary CAST_SDWORD = new OperatorCastSDWord(2);
public static final OperatorUnary CAST_BOOL= new OperatorCastBool(2);
public static final OperatorUnary SIZEOF = new OperatorSizeOf(2);
public static final OperatorBinary MULTIPLY = new OperatorMultiply(3);
public static final OperatorBinary DIVIDE = new OperatorDivide(3);
public static final OperatorBinary MODULO = new OperatorModulo(3);

View File

@ -21,7 +21,7 @@ public interface SymbolType {
/** Signed double word (4 bytes, 32 bits). */
SymbolTypeInteger SDWORD = new SymbolTypeInteger("signed dword", -2_147_483_648, 2_147_483_647, true, 32);
/** String value (treated like byte* ). */
SymbolTypeNamed STRING = new SymbolTypeNamed("string", -1);
SymbolTypeNamed STRING = new SymbolTypeNamed("string", 99);
/** Boolean value. */
SymbolTypeNamed BOOLEAN = new SymbolTypeNamed("bool", 1);
/** Numeric floating point value. */

View File

@ -34,7 +34,7 @@ public class SymbolTypeInference {
try {
ConstantValue constRValue = (ConstantValue) rValue;
ConstantLiteral literalRValue = constRValue.calculateLiteral(programScope);
ConstantValue value = operator.calculateLiteral(literalRValue);
ConstantValue value = operator.calculateLiteral(literalRValue, programScope);
return value.getType(programScope);
} catch(ConstantNotLiteral e) {
// Value literal cannot be calculated

View File

@ -26,7 +26,19 @@ public class SymbolTypeMulti implements SymbolType {
@Override
public int getSizeBytes() {
return -1;
// Find the minimal sizeof - and return that
Integer size = null;
for(SymbolType type : types) {
if(size==null) {
size = type.getSizeBytes();
} else if(size>type.getSizeBytes()) {
size = type.getSizeBytes();
}
}
if(size==null) {
return -1;
}
return size;
}
@Override

View File

@ -1,7 +1,6 @@
package dk.camelot64.kickc.model.values;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.OperatorUnary;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.symbols.ProgramScope;
@ -34,7 +33,7 @@ public class ConstantCastValue implements ConstantValue {
public ConstantLiteral calculateLiteral(ProgramScope scope) {
ConstantLiteral valueLiteral = value.calculateLiteral(scope);
OperatorUnary castOperator = Operators.getCastUnary(toType);
return castOperator.calculateLiteral(valueLiteral);
return castOperator.calculateLiteral(valueLiteral, scope);
}
public SymbolType getToType() {

View File

@ -38,7 +38,7 @@ public class ConstantUnary implements ConstantValue {
@Override
public ConstantLiteral calculateLiteral(ProgramScope scope) {
return operator.calculateLiteral(operand.calculateLiteral(scope));
return operator.calculateLiteral(operand.calculateLiteral(scope), scope);
}
@Override

View File

@ -112,7 +112,7 @@ commaExpr
expr
: '(' commaExpr ')' #exprPar
| expr '(' parameterList? ')' #exprCall
| 'sizeof' '(' typeDecl ')' #exprSizeOfType
| 'sizeof' '(' ( typeDecl | expr ) ')' #exprSizeOf
| expr '[' commaExpr ']' #exprArray
| '(' typeDecl ')' expr #exprCast
| ('--' | '++' ) expr #exprPreMod

View File

@ -647,18 +647,6 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprChar(KickCParser.ExprCharContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx) { }
/**
* {@inheritDoc}
*
@ -707,6 +695,18 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprPar(KickCParser.ExprParContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprSizeOf(KickCParser.ExprSizeOfContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprSizeOf(KickCParser.ExprSizeOfContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -382,13 +382,6 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprChar(KickCParser.ExprCharContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@ -417,6 +410,13 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprPar(KickCParser.ExprParContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprSizeOf(KickCParser.ExprSizeOfContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -617,18 +617,6 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitExprChar(KickCParser.ExprCharContext ctx);
/**
* Enter a parse tree produced by the {@code exprSizeOfType}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
*/
void enterExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx);
/**
* Exit a parse tree produced by the {@code exprSizeOfType}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
*/
void exitExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx);
/**
* Enter a parse tree produced by the {@code initList}
* labeled alternative in {@link KickCParser#expr}.
@ -677,6 +665,18 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitExprPar(KickCParser.ExprParContext ctx);
/**
* Enter a parse tree produced by the {@code exprSizeOf}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
*/
void enterExprSizeOf(KickCParser.ExprSizeOfContext ctx);
/**
* Exit a parse tree produced by the {@code exprSizeOf}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
*/
void exitExprSizeOf(KickCParser.ExprSizeOfContext ctx);
/**
* Enter a parse tree produced by the {@code exprString}
* labeled alternative in {@link KickCParser#expr}.

File diff suppressed because it is too large Load Diff

View File

@ -368,13 +368,6 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitExprChar(KickCParser.ExprCharContext ctx);
/**
* Visit a parse tree produced by the {@code exprSizeOfType}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx);
/**
* Visit a parse tree produced by the {@code initList}
* labeled alternative in {@link KickCParser#expr}.
@ -403,6 +396,13 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitExprPar(KickCParser.ExprParContext ctx);
/**
* Visit a parse tree produced by the {@code exprSizeOf}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprSizeOf(KickCParser.ExprSizeOfContext ctx);
/**
* Visit a parse tree produced by the {@code exprString}
* labeled alternative in {@link KickCParser#expr}.

View File

@ -5,6 +5,7 @@ import dk.camelot64.kickc.NumberParser;
import dk.camelot64.kickc.asm.AsmClobber;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.*;
@ -1179,30 +1180,24 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
@Override
public Object visitExprSizeOfType(KickCParser.ExprSizeOfTypeContext ctx) {
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
String typeConstName = getSizeofName(type);
ConstantVar typeSizeConstant = program.getScope().getConstant(typeConstName);
if(typeSizeConstant ==null) {
// Constant not found - create it
long typeSize = type.getSizeBytes();
typeSizeConstant = new ConstantVar(typeConstName, program.getScope(), SymbolType.BYTE, new ConstantInteger(typeSize));
program.getScope().add(typeSizeConstant);
}
return typeSizeConstant.getRef();
}
private String getSizeofName(SymbolType type) {
if(type instanceof SymbolTypePointer) {
return "SIZEOF_POINTER";
public Object visitExprSizeOf(KickCParser.ExprSizeOfContext ctx) {
if(ctx.typeDecl()!=null) {
// sizeof(type) - add directly
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
return OperatorSizeOf.getSizeOfConstantVar(program.getScope(), type);
} else {
return "SIZEOF_"+type.getTypeName().toUpperCase().replace(" ", "_");
// sizeof(expression) - add a unary expression to be resolved later
RValue child = (RValue) this.visit(ctx.expr());
VariableIntermediate tmpVar = getCurrentScope().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmt = new StatementAssignment(tmpVarRef, Operators.SIZEOF, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
sequence.addStatement(stmt);
return tmpVarRef;
}
}
@Override
public Object visitExprCall(KickCParser.ExprCallContext ctx) {
List<RValue> parameters;
KickCParser.ParameterListContext parameterList = ctx.parameterList();
if(parameterList != null) {

View File

@ -4,10 +4,7 @@ import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.OperatorBinary;
import dk.camelot64.kickc.model.operators.OperatorCastPtr;
import dk.camelot64.kickc.model.operators.OperatorUnary;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.operators.*;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
@ -302,39 +299,11 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
}
static ConstantValue createUnary(OperatorUnary operator, ConstantValue c) {
if(operator instanceof OperatorCastPtr) {
return new ConstantUnary(operator, c);
}
switch(operator.getOperator()) {
case "-":
case "+":
case "++":
case "--":
case "<":
case ">":
case "((byte))":
case "((signed byte))":
case "((sbyte))":
case "((word))":
case "((signed word))":
case "((dword))":
case "((signed dword))":
case "((byte*))":
case "((signed byte*))":
case "((word*))":
case "((signed word*))":
case "((dword*))":
case "((signed dword*))":
case "((boolean*))":
case "!":
case "~":
return new ConstantUnary(operator, c);
case "*": { // pointer dereference - not constant
return null;
}
default:
throw new RuntimeException("Unhandled Unary Operator " + operator.getOperator());
if(Operators.DEREF.equals(operator)) {
// Pointer dereferencing is not constant
return null;
}
return new ConstantUnary(operator, c);
}
static ConstantValue createBinary(ConstantValue c1, OperatorBinary operator, ConstantValue c2, ProgramScope programScope) {

View File

@ -0,0 +1,130 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ConstantNotLiteral;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
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.ConstantVar;
import dk.camelot64.kickc.model.symbols.SymbolVariable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeArray;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.values.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Simplifies sizeof() operators whenever the expression is constant
*/
public class Pass2SizeOfSimplification extends Pass2SsaOptimization {
public Pass2SizeOfSimplification(Program program) {
super(program);
}
@Override
public boolean step() {
AtomicBoolean modified = new AtomicBoolean(false);
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) {
if(statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
if(Operators.SIZEOF.equals(assignment.getOperator())) {
if(assignment.getrValue2() instanceof SymbolVariableRef) {
SymbolVariableRef symbolRef = (SymbolVariableRef) assignment.getrValue2();
SymbolVariable symbolVar = (SymbolVariable) getScope().getSymbol(symbolRef);
SymbolType symbolType = symbolVar.getType();
if(!(symbolType instanceof SymbolTypeArray)) {
getLog().append("Resolving sizeof() " + assignment.toString(getProgram(), false));
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), symbolType);
assignment.setrValue2(sizeOfConstantVar);
assignment.setOperator(null);
modified.set(true);
}
}
}
}
}
}
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof ConstantUnary) {
ConstantUnary unary = (ConstantUnary) programValue.get();
if(unary.getOperator().equals(Operators.SIZEOF)) {
ConstantValue operand = unary.getOperand();
resolveConstantSizeOf(modified, programValue, unary, operand);
}
}
}
);
return modified.get();
}
public void resolveConstantSizeOf(AtomicBoolean modified, ProgramValue programValue, ConstantUnary unary, ConstantValue operand) {
if(operand instanceof ConstantRef) {
ConstantVar constant = getScope().getConstant((ConstantRef) operand);
SymbolType symbolType = constant.getType();
if(symbolType instanceof SymbolTypeArray) {
SymbolTypeArray arrayType = (SymbolTypeArray) symbolType;
RValue arraySize = arrayType.getSize();
if(arraySize instanceof ConstantValue) {
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary((ConstantValue) arraySize, Operators.MULTIPLY, sizeOfConstantVar));
modified.set(true);
} else if(constant.getValue() instanceof ConstantArrayList) {
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
int size = ((ConstantArrayList) constant.getValue()).getElements().size();
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary(new ConstantInteger((long) size), Operators.MULTIPLY, sizeOfConstantVar));
modified.set(true);
} else {
// Try to calculate the literal to check if it is a string
ConstantLiteral stringLiteral = null;
try {
stringLiteral = constant.getValue().calculateLiteral(getProgram().getScope());
} catch(ConstantNotLiteral e) {
// Ignore
}
if(stringLiteral instanceof ConstantString) {
ConstantString constString = (ConstantString) stringLiteral;
int length = constString.getString().length();
ConstantRef sizeOfChar = OperatorSizeOf.getSizeOfConstantVar(getScope(), SymbolType.BYTE);
programValue.set(new ConstantBinary(new ConstantInteger((long) length), Operators.MULTIPLY, sizeOfChar));
modified.set(true);
} else {
throw new CompileError("Not implemented!");
}
}
} else if(symbolType instanceof SymbolTypePointer ){
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), symbolType);
programValue.set(sizeOfConstantVar);
modified.set(true);
} else {
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
ConstantLiteral literal = operand.calculateLiteral(getProgram().getScope());
SymbolType constType = literal.getType(getProgram().getScope());
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), constType);
programValue.set(sizeOfConstantVar);
modified.set(true);
}
} else {
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
ConstantLiteral literal = operand.calculateLiteral(getProgram().getScope());
SymbolType constType = literal.getType(getProgram().getScope());
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), constType);
programValue.set(sizeOfConstantVar);
modified.set(true);
}
}
}

View File

@ -337,11 +337,11 @@ public class Pass4CodeGeneration {
}
}
}
Collection<ConstantRef> constRefConsts = program.getVariableReferenceInfos().getConstRefConsts(constantVar.getRef());
if(constRefConsts != null) {
for(ConstantRef constRefConst : constRefConsts) {
ConstantVar refConst = program.getScope().getConstant(constRefConst);
if(!refConst.getScope().getRef().equals(scopeRef)) {
Collection<SymbolVariableRef> symbolRefConsts = program.getVariableReferenceInfos().getSymbolRefConsts(constantVar.getRef());
if(symbolRefConsts != null) {
for(SymbolVariableRef symbolRefConst : symbolRefConsts) {
SymbolVariable symbolRefVar = (SymbolVariable) program.getScope().getSymbol(symbolRefConst);
if(!symbolRefVar.getScope().getRef().equals(scopeRef)) {
// Used in constant in another scope - generate label
useLabel = true;
break;

View File

@ -37,6 +37,11 @@ public class TestPrograms {
// compileAndCompare("pointer-cast-3");
//}
@Test
public void testSizeofExpression() throws IOException, URISyntaxException {
compileAndCompare("sizeof-expr");
}
@Test
public void testSizeofTypes() throws IOException, URISyntaxException {
compileAndCompare("sizeof-types");

View File

@ -0,0 +1,42 @@
// Tests the sizeof() operator on epressions
const byte* SCREEN = $400;
void main() {
byte idx = 0;
// Simple types
volatile byte b = 0;
volatile word w = 0;
// Pointers
byte* bp = $1000;
word* wp = &w;
// Arrays
byte[3] ba;
word[3] wa;
byte sz = 15;
byte[sz+2] bb;
byte[] bc = { 1, 2, 3, 4 };
// Strings
byte[] sa = "camelot";
byte[] sb = "cml"+" "+"rules";
SCREEN[idx++] = '0'+sizeof(0);
SCREEN[idx++] = '0'+sizeof(idx);
SCREEN[idx++] = '0'+sizeof(b);
SCREEN[idx++] = '0'+sizeof(b*2);
idx++;
SCREEN[idx++] = '0'+sizeof($43ff);
SCREEN[idx++] = '0'+sizeof(w);
idx++;
SCREEN[idx++] = '0'+sizeof(bp);
SCREEN[idx++] = '0'+sizeof(wp);
idx++;
SCREEN[idx++] = '0'+sizeof(ba);
SCREEN[idx++] = '0'+sizeof(wa);
SCREEN[idx++] = '0'+sizeof(bb);
SCREEN[idx++] = '0'+sizeof(bc);
SCREEN[idx++] = '0'+sizeof(sa);
SCREEN[idx++] = '0'+sizeof(sb);
}

View File

@ -0,0 +1,42 @@
// Tests the sizeof() operator on epressions
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_BYTE = 1
.const SIZEOF_WORD = 2
.const SIZEOF_POINTER = 2
main: {
.const sz = $f
.label b = 2
.label w = 3
// Simple types
lda #0
sta b
sta w
sta w+1
lda #'0'+SIZEOF_BYTE
sta SCREEN
sta SCREEN+1
sta SCREEN+2
sta SCREEN+3
lda #'0'+SIZEOF_WORD
sta SCREEN+5
sta SCREEN+6
lda #'0'+SIZEOF_POINTER
sta SCREEN+8
sta SCREEN+9
lda #'0'+3*SIZEOF_BYTE
sta SCREEN+$b
lda #'0'+3*SIZEOF_WORD
sta SCREEN+$c
lda #'0'+(sz+2)*SIZEOF_BYTE
sta SCREEN+$d
lda #'0'+4*SIZEOF_BYTE
sta SCREEN+$e
lda #'0'+8*SIZEOF_BYTE
sta SCREEN+$f
lda #'0'+$c*SIZEOF_BYTE
sta SCREEN+$10
rts
}

View File

@ -0,0 +1,30 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[5] (word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[6] *((const byte*) SCREEN#0) ← (byte) '0'+(const byte) SIZEOF_BYTE
[7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) '0'+(const byte) SIZEOF_BYTE
[8] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) '0'+(const byte) SIZEOF_BYTE
[9] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) '0'+(const byte) SIZEOF_BYTE
[10] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5) ← (byte) '0'+(const byte) SIZEOF_WORD
[11] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) '0'+(const byte) SIZEOF_WORD
[12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 8) ← (byte) '0'+(const byte) SIZEOF_POINTER
[13] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 9) ← (byte) '0'+(const byte) SIZEOF_POINTER
[14] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $b) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE
[15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $c) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD
[16] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $d) ← (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE
[17] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $e) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE
[18] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $f) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE
[19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $10) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE
to:main::@return
main::@return: scope:[main] from main
[20] return
to:@return

View File

@ -0,0 +1,804 @@
Identified constant variable (byte*) main::bp
Identified constant variable (byte) main::sz
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
to:@1
main: scope:[main] from @1
(byte) main::idx#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) main::bp#0 ← ((byte*)) (word/signed word/dword/signed dword) $1000
(word*~) main::$0 ← & (word) main::w#0
(word*) main::wp#0 ← (word*~) main::$0
(byte[3]) main::ba#0 ← { fill( 3, 0) }
(word[3]) main::wa#0 ← { fill( 3, 0) }
(byte) main::sz#0 ← (byte/signed byte/word/signed word/dword/signed dword) $f
(byte/signed word/word/dword/signed dword~) main::$1 ← (byte) main::sz#0 + (byte/signed byte/word/signed word/dword/signed dword) 2
(byte[main::$1]) main::bb#0 ← { fill( main::$1, 0) }
(byte[]) main::bc#0 ← { (byte/signed byte/word/signed word/dword/signed dword) 1, (byte/signed byte/word/signed word/dword/signed dword) 2, (byte/signed byte/word/signed word/dword/signed dword) 3, (byte/signed byte/word/signed word/dword/signed dword) 4 }
(byte[]) main::sa#0 ← (const string) main::$33
(string~) main::$2 ← (const string) main::$34 + (const string) main::$35
(string~) main::$3 ← (string~) main::$2 + (const string) main::$36
(byte[]) main::sb#0 ← (string~) main::$3
(byte/signed byte/word/signed word/dword/signed dword~) main::$4 ← sizeof (byte/signed byte/word/signed word/dword/signed dword) 0
(byte/signed word/word/dword/signed dword~) main::$5 ← (byte) '0' + (byte/signed byte/word/signed word/dword/signed dword~) main::$4
*((byte*) SCREEN#0 + (byte) main::idx#0) ← (byte/signed word/word/dword/signed dword~) main::$5
(byte) main::idx#1 ← ++ (byte) main::idx#0
(byte~) main::$6 ← sizeof (byte) main::idx#1
(byte~) main::$7 ← (byte) '0' + (byte~) main::$6
*((byte*) SCREEN#0 + (byte) main::idx#1) ← (byte~) main::$7
(byte) main::idx#2 ← ++ (byte) main::idx#1
(byte~) main::$8 ← sizeof (byte) main::b#0
(byte~) main::$9 ← (byte) '0' + (byte~) main::$8
*((byte*) SCREEN#0 + (byte) main::idx#2) ← (byte~) main::$9
(byte) main::idx#3 ← ++ (byte) main::idx#2
(byte/signed word/word/dword/signed dword~) main::$10 ← (byte) main::b#0 * (byte/signed byte/word/signed word/dword/signed dword) 2
(byte~) main::$11 ← sizeof (byte/signed word/word/dword/signed dword~) main::$10
(byte~) main::$12 ← (byte) '0' + (byte~) main::$11
*((byte*) SCREEN#0 + (byte) main::idx#3) ← (byte~) main::$12
(byte) main::idx#4 ← ++ (byte) main::idx#3
(byte) main::idx#5 ← ++ (byte) main::idx#4
(byte/signed byte/word/signed word/dword/signed dword~) main::$13 ← sizeof (word/signed word/dword/signed dword) $43ff
(byte/signed word/word/dword/signed dword~) main::$14 ← (byte) '0' + (byte/signed byte/word/signed word/dword/signed dword~) main::$13
*((byte*) SCREEN#0 + (byte) main::idx#5) ← (byte/signed word/word/dword/signed dword~) main::$14
(byte) main::idx#6 ← ++ (byte) main::idx#5
(byte~) main::$15 ← sizeof (word) main::w#0
(byte~) main::$16 ← (byte) '0' + (byte~) main::$15
*((byte*) SCREEN#0 + (byte) main::idx#6) ← (byte~) main::$16
(byte) main::idx#7 ← ++ (byte) main::idx#6
(byte) main::idx#8 ← ++ (byte) main::idx#7
(byte~) main::$17 ← sizeof (byte*) main::bp#0
(byte~) main::$18 ← (byte) '0' + (byte~) main::$17
*((byte*) SCREEN#0 + (byte) main::idx#8) ← (byte~) main::$18
(byte) main::idx#9 ← ++ (byte) main::idx#8
(byte~) main::$19 ← sizeof (word*) main::wp#0
(byte~) main::$20 ← (byte) '0' + (byte~) main::$19
*((byte*) SCREEN#0 + (byte) main::idx#9) ← (byte~) main::$20
(byte) main::idx#10 ← ++ (byte) main::idx#9
(byte) main::idx#11 ← ++ (byte) main::idx#10
(byte~) main::$21 ← sizeof (byte[3]) main::ba#0
(byte~) main::$22 ← (byte) '0' + (byte~) main::$21
*((byte*) SCREEN#0 + (byte) main::idx#11) ← (byte~) main::$22
(byte) main::idx#12 ← ++ (byte) main::idx#11
(byte~) main::$23 ← sizeof (word[3]) main::wa#0
(byte~) main::$24 ← (byte) '0' + (byte~) main::$23
*((byte*) SCREEN#0 + (byte) main::idx#12) ← (byte~) main::$24
(byte) main::idx#13 ← ++ (byte) main::idx#12
(byte~) main::$25 ← sizeof (byte[main::$1]) main::bb#0
(byte~) main::$26 ← (byte) '0' + (byte~) main::$25
*((byte*) SCREEN#0 + (byte) main::idx#13) ← (byte~) main::$26
(byte) main::idx#14 ← ++ (byte) main::idx#13
(byte~) main::$27 ← sizeof (byte[]) main::bc#0
(byte~) main::$28 ← (byte) '0' + (byte~) main::$27
*((byte*) SCREEN#0 + (byte) main::idx#14) ← (byte~) main::$28
(byte) main::idx#15 ← ++ (byte) main::idx#14
(byte~) main::$29 ← sizeof (byte[]) main::sa#0
(byte~) main::$30 ← (byte) '0' + (byte~) main::$29
*((byte*) SCREEN#0 + (byte) main::idx#15) ← (byte~) main::$30
(byte) main::idx#16 ← ++ (byte) main::idx#15
(byte~) main::$31 ← sizeof (byte[]) main::sb#0
(byte~) main::$32 ← (byte) '0' + (byte~) main::$31
*((byte*) SCREEN#0 + (byte) main::idx#16) ← (byte~) main::$32
(byte) main::idx#17 ← ++ (byte) main::idx#16
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(void()) main()
(word*~) main::$0
(byte/signed word/word/dword/signed dword~) main::$1
(byte/signed word/word/dword/signed dword~) main::$10
(byte~) main::$11
(byte~) main::$12
(byte/signed byte/word/signed word/dword/signed dword~) main::$13
(byte/signed word/word/dword/signed dword~) main::$14
(byte~) main::$15
(byte~) main::$16
(byte~) main::$17
(byte~) main::$18
(byte~) main::$19
(string~) main::$2
(byte~) main::$20
(byte~) main::$21
(byte~) main::$22
(byte~) main::$23
(byte~) main::$24
(byte~) main::$25
(byte~) main::$26
(byte~) main::$27
(byte~) main::$28
(byte~) main::$29
(string~) main::$3
(byte~) main::$30
(byte~) main::$31
(byte~) main::$32
(const string) main::$33 = (string) "camelot@"
(const string) main::$34 = (string) "cml@"
(const string) main::$35 = (string) " @"
(const string) main::$36 = (string) "rules@"
(byte/signed byte/word/signed word/dword/signed dword~) main::$4
(byte/signed word/word/dword/signed dword~) main::$5
(byte~) main::$6
(byte~) main::$7
(byte~) main::$8
(byte~) main::$9
(label) main::@return
(byte) main::b
(byte) main::b#0
(byte[3]) main::ba
(byte[3]) main::ba#0
(byte[main::$1]) main::bb
(byte[main::$1]) main::bb#0
(byte[]) main::bc
(byte[]) main::bc#0
(byte*) main::bp
(byte*) main::bp#0
(byte) main::idx
(byte) main::idx#0
(byte) main::idx#1
(byte) main::idx#10
(byte) main::idx#11
(byte) main::idx#12
(byte) main::idx#13
(byte) main::idx#14
(byte) main::idx#15
(byte) main::idx#16
(byte) main::idx#17
(byte) main::idx#2
(byte) main::idx#3
(byte) main::idx#4
(byte) main::idx#5
(byte) main::idx#6
(byte) main::idx#7
(byte) main::idx#8
(byte) main::idx#9
(byte[]) main::sa
(byte[]) main::sa#0
(byte[]) main::sb
(byte[]) main::sb#0
(byte) main::sz
(byte) main::sz#0
(word) main::w
(word) main::w#0
(word[3]) main::wa
(word[3]) main::wa#0
(word*) main::wp
(word*) main::wp#0
Culled Empty Block (label) @2
Successful SSA optimization Pass2CullEmptyBlocks
Alias (word*) main::wp#0 = (word*~) main::$0
Alias (byte[]) main::sb#0 = (string~) main::$3
Successful SSA optimization Pass2AliasElimination
Constant (const byte*) SCREEN#0 = ((byte*))$400
Constant (const byte) main::idx#0 = 0
Constant (const byte*) main::bp#0 = ((byte*))$1000
Constant (const word*) main::wp#0 = &main::w#0
Constant (const byte[3]) main::ba#0 = { fill( 3, 0) }
Constant (const word[3]) main::wa#0 = { fill( 3, 0) }
Constant (const byte) main::sz#0 = $f
Constant (const byte[]) main::bc#0 = { 1, 2, 3, 4 }
Constant (const byte[]) main::sa#0 = main::$33
Constant (const string) main::$2 = "cml@"+" @"
Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$4 = sizeof 0
Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$13 = sizeof $43ff
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte/signed word/word/dword/signed dword) main::$1 = main::sz#0+2
Constant (const byte[]) main::sb#0 = "cml@"+" @"+"rules@"
Constant (const byte/signed word/word/dword/signed dword) main::$5 = '0'+main::$4
Constant (const byte) main::idx#1 = ++main::idx#0
Constant (const byte/signed word/word/dword/signed dword) main::$14 = '0'+main::$13
Constant (const byte) main::$17 = sizeof main::bp#0
Constant (const byte) main::$19 = sizeof main::wp#0
Constant (const byte) main::$21 = sizeof main::ba#0
Constant (const byte) main::$23 = sizeof main::wa#0
Constant (const byte) main::$27 = sizeof main::bc#0
Constant (const byte) main::$29 = sizeof main::sa#0
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte[main::$1]) main::bb#0 = { fill( main::$1, 0) }
Constant (const byte) main::$6 = sizeof main::idx#1
Constant (const byte) main::idx#2 = ++main::idx#1
Constant (const byte) main::$18 = '0'+main::$17
Constant (const byte) main::$20 = '0'+main::$19
Constant (const byte) main::$22 = '0'+main::$21
Constant (const byte) main::$24 = '0'+main::$23
Constant (const byte) main::$28 = '0'+main::$27
Constant (const byte) main::$30 = '0'+main::$29
Constant (const byte) main::$31 = sizeof main::sb#0
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::$7 = '0'+main::$6
Constant (const byte) main::idx#3 = ++main::idx#2
Constant (const byte) main::$25 = sizeof main::bb#0
Constant (const byte) main::$32 = '0'+main::$31
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#4 = ++main::idx#3
Constant (const byte) main::$26 = '0'+main::$25
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#5 = ++main::idx#4
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#6 = ++main::idx#5
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#7 = ++main::idx#6
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#8 = ++main::idx#7
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#9 = ++main::idx#8
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#10 = ++main::idx#9
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#11 = ++main::idx#10
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#12 = ++main::idx#11
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#13 = ++main::idx#12
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#14 = ++main::idx#13
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#15 = ++main::idx#14
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#16 = ++main::idx#15
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::idx#17 = ++main::idx#16
Successful SSA optimization Pass2ConstantIdentification
Consolidated array index constant in *(SCREEN#0+main::idx#0)
Consolidated array index constant in *(SCREEN#0+main::idx#1)
Consolidated array index constant in *(SCREEN#0+main::idx#2)
Consolidated array index constant in *(SCREEN#0+main::idx#3)
Consolidated array index constant in *(SCREEN#0+main::idx#5)
Consolidated array index constant in *(SCREEN#0+main::idx#6)
Consolidated array index constant in *(SCREEN#0+main::idx#8)
Consolidated array index constant in *(SCREEN#0+main::idx#9)
Consolidated array index constant in *(SCREEN#0+main::idx#11)
Consolidated array index constant in *(SCREEN#0+main::idx#12)
Consolidated array index constant in *(SCREEN#0+main::idx#13)
Consolidated array index constant in *(SCREEN#0+main::idx#14)
Consolidated array index constant in *(SCREEN#0+main::idx#15)
Consolidated array index constant in *(SCREEN#0+main::idx#16)
Successful SSA optimization Pass2ConstantAdditionElimination
Successful SSA optimization PassNEliminateUnusedVars
Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$10 ← (byte) main::b#0 * (byte/signed byte/word/signed word/dword/signed dword) 2
Successful SSA optimization Pass2MultiplyToShiftRewriting
Resolving sizeof() (byte~) main::$8 ← sizeof (byte) main::b#0
Resolving sizeof() (byte~) main::$11 ← sizeof (byte/signed word/word/dword/signed dword~) main::$10
Resolving sizeof() (byte~) main::$15 ← sizeof (word) main::w#0
Resolving sizeof() sizeof (byte/signed byte/word/signed word/dword/signed dword) 0
Resolving sizeof() sizeof (word/signed word/dword/signed dword) $43ff
Resolving sizeof() sizeof (const byte*) main::bp#0
Resolving sizeof() sizeof (const word*) main::wp#0
Resolving sizeof() sizeof (const byte[3]) main::ba#0
Resolving sizeof() sizeof (const word[3]) main::wa#0
Resolving sizeof() sizeof (const byte[]) main::bc#0
Resolving sizeof() sizeof (const byte) main::idx#1
Resolving sizeof() sizeof (const byte[main::$1]) main::bb#0
Successful SSA optimization Pass2SizeOfSimplification
Constant (const byte) main::$8 = SIZEOF_BYTE
Constant (const byte) main::$11 = SIZEOF_BYTE
Constant (const byte) main::$15 = SIZEOF_WORD
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::$9 = '0'+main::$8
Constant (const byte) main::$12 = '0'+main::$11
Constant (const byte) main::$16 = '0'+main::$15
Successful SSA optimization Pass2ConstantIdentification
Inferred type updated to byte in [5] (byte/signed word/word/dword/signed dword~) main::$10 ← (byte) main::b#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
Successful SSA optimization PassNEliminateUnusedVars
Successful SSA optimization PassNEliminateUnusedVars
Inlining constant with different constant siblings (const byte) main::idx#0
Inlining constant with different constant siblings (const byte) main::idx#1
Inlining constant with different constant siblings (const byte) main::idx#2
Inlining constant with different constant siblings (const byte) main::idx#3
Inlining constant with different constant siblings (const byte) main::idx#4
Inlining constant with different constant siblings (const byte) main::idx#5
Inlining constant with different constant siblings (const byte) main::idx#6
Inlining constant with different constant siblings (const byte) main::idx#7
Inlining constant with different constant siblings (const byte) main::idx#8
Inlining constant with different constant siblings (const byte) main::idx#9
Inlining constant with different constant siblings (const byte) main::idx#10
Inlining constant with different constant siblings (const byte) main::idx#11
Inlining constant with different constant siblings (const byte) main::idx#12
Inlining constant with different constant siblings (const byte) main::idx#13
Inlining constant with different constant siblings (const byte) main::idx#14
Inlining constant with different constant siblings (const byte) main::idx#15
Inlining constant with different constant siblings (const byte) main::idx#16
Constant inlined main::idx#16 = ++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#12 = ++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#13 = ++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#14 = ++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#15 = ++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$12 = (byte) '0'+(const byte) SIZEOF_BYTE
Constant inlined main::$13 = (const byte) SIZEOF_WORD
Constant inlined main::$14 = (byte) '0'+(const byte) SIZEOF_WORD
Constant inlined main::$15 = (const byte) SIZEOF_WORD
Constant inlined main::$30 = (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE
Constant inlined main::$31 = (byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE
Constant inlined main::$32 = (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE
Constant inlined main::$11 = (const byte) SIZEOF_BYTE
Constant inlined main::$16 = (byte) '0'+(const byte) SIZEOF_WORD
Constant inlined main::$17 = (const byte) SIZEOF_POINTER
Constant inlined main::$18 = (byte) '0'+(const byte) SIZEOF_POINTER
Constant inlined main::$19 = (const byte) SIZEOF_POINTER
Constant inlined main::$23 = (byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD
Constant inlined main::$24 = (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD
Constant inlined main::$25 = (const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE
Constant inlined main::$26 = (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE
Constant inlined main::$20 = (byte) '0'+(const byte) SIZEOF_POINTER
Constant inlined main::$21 = (byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE
Constant inlined main::$22 = (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE
Constant inlined main::idx#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#1 = ++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#2 = ++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$1 = (const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2
Constant inlined main::$27 = (byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE
Constant inlined main::idx#3 = ++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$28 = (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE
Constant inlined main::idx#4 = ++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$29 = (byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE
Constant inlined main::idx#5 = ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#6 = ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$5 = (byte) '0'+(const byte) SIZEOF_BYTE
Constant inlined main::idx#7 = ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$6 = (const byte) SIZEOF_BYTE
Constant inlined main::idx#8 = ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#9 = ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::idx#10 = ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$4 = (const byte) SIZEOF_BYTE
Constant inlined main::idx#11 = ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$9 = (byte) '0'+(const byte) SIZEOF_BYTE
Constant inlined main::$7 = (byte) '0'+(const byte) SIZEOF_BYTE
Constant inlined main::$8 = (const byte) SIZEOF_BYTE
Successful SSA optimization Pass2ConstantInlining
Simplifying constant plus zero SCREEN#0+0
Simplifying constant integer increment ++0
Simplifying constant integer increment ++0
Simplifying constant integer increment ++1
Simplifying constant integer increment ++2
Simplifying constant integer increment ++3
Simplifying constant integer increment ++4
Simplifying constant integer increment ++5
Simplifying constant integer increment ++6
Simplifying constant integer increment ++7
Simplifying constant integer increment ++8
Simplifying constant integer increment ++9
Simplifying constant integer increment ++$a
Simplifying constant integer increment ++$b
Successful SSA optimization Pass2ConstantSimplification
Simplifying constant integer increment ++1
Simplifying constant integer increment ++2
Simplifying constant integer increment ++4
Simplifying constant integer increment ++5
Simplifying constant integer increment ++7
Simplifying constant integer increment ++8
Simplifying constant integer increment ++$a
Simplifying constant integer increment ++$b
Simplifying constant integer increment ++$c
Simplifying constant integer increment ++$c
Simplifying constant integer increment ++$d
Simplifying constant integer increment ++$e
Successful SSA optimization Pass2ConstantSimplification
Simplifying constant integer increment ++$d
Simplifying constant integer increment ++$e
Simplifying constant integer increment ++$f
Successful SSA optimization Pass2ConstantSimplification
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[5] (word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[6] *((const byte*) SCREEN#0) ← (byte) '0'+(const byte) SIZEOF_BYTE
[7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) '0'+(const byte) SIZEOF_BYTE
[8] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) '0'+(const byte) SIZEOF_BYTE
[9] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) '0'+(const byte) SIZEOF_BYTE
[10] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5) ← (byte) '0'+(const byte) SIZEOF_WORD
[11] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) '0'+(const byte) SIZEOF_WORD
[12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 8) ← (byte) '0'+(const byte) SIZEOF_POINTER
[13] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 9) ← (byte) '0'+(const byte) SIZEOF_POINTER
[14] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $b) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE
[15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $c) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD
[16] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $d) ← (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE
[17] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $e) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE
[18] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $f) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE
[19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $10) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE
to:main::@return
main::@return: scope:[main] from main
[20] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte*) SCREEN
(void()) main()
(byte) main::b
(byte) main::b#0 20.0
(byte[3]) main::ba
(byte[main::sz#0+2]) main::bb
(byte[]) main::bc
(byte*) main::bp
(byte) main::idx
(byte[]) main::sa
(byte[]) main::sb
(byte) main::sz
(word) main::w
(word) main::w#0 20.0
(word[3]) main::wa
(word*) main::wp
Initial phi equivalence classes
Complete equivalence classes
[ main::b#0 ]
[ main::w#0 ]
Allocated zp ZP_BYTE:2 [ main::b#0 ]
Allocated zp ZP_WORD:3 [ main::w#0 ]
INITIAL ASM
//SEG0 File Comments
// Tests the sizeof() operator on epressions
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label SCREEN = $400
.const SIZEOF_BYTE = 1
.const SIZEOF_WORD = 2
.const SIZEOF_POINTER = 2
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
jsr main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG8 @end
bend:
//SEG9 main
main: {
.const sz = $f
.label b = 2
.label w = 3
//SEG10 [4] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// Simple types
lda #0
sta b
//SEG11 [5] (word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vwuz1=vbuc1
lda #0
sta w
lda #0
sta w+1
//SEG12 [6] *((const byte*) SCREEN#0) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN
//SEG13 [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN+1
//SEG14 [8] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN+2
//SEG15 [9] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN+3
//SEG16 [10] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5) ← (byte) '0'+(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_WORD
sta SCREEN+5
//SEG17 [11] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) '0'+(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_WORD
sta SCREEN+6
//SEG18 [12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 8) ← (byte) '0'+(const byte) SIZEOF_POINTER -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_POINTER
sta SCREEN+8
//SEG19 [13] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 9) ← (byte) '0'+(const byte) SIZEOF_POINTER -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_POINTER
sta SCREEN+9
//SEG20 [14] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $b) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+3*SIZEOF_BYTE
sta SCREEN+$b
//SEG21 [15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $c) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+3*SIZEOF_WORD
sta SCREEN+$c
//SEG22 [16] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $d) ← (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+(sz+2)*SIZEOF_BYTE
sta SCREEN+$d
//SEG23 [17] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $e) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+4*SIZEOF_BYTE
sta SCREEN+$e
//SEG24 [18] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $f) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+8*SIZEOF_BYTE
sta SCREEN+$f
//SEG25 [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $10) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+$c*SIZEOF_BYTE
sta SCREEN+$10
jmp breturn
//SEG26 main::@return
breturn:
//SEG27 [20] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] (word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN#0) ← (byte) '0'+(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) '0'+(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) '0'+(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) '0'+(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5) ← (byte) '0'+(const byte) SIZEOF_WORD [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) '0'+(const byte) SIZEOF_WORD [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 8) ← (byte) '0'+(const byte) SIZEOF_POINTER [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 9) ← (byte) '0'+(const byte) SIZEOF_POINTER [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [14] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $b) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $c) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [16] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $d) ← (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [17] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $e) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [18] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $f) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $10) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:2 [ main::b#0 ] : zp ZP_BYTE:2 ,
Potential registers zp ZP_WORD:3 [ main::w#0 ] : zp ZP_WORD:3 ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 20: zp ZP_BYTE:2 [ main::b#0 ] 20: zp ZP_WORD:3 [ main::w#0 ]
Uplift Scope []
Uplifting [main] best 120 combination zp ZP_BYTE:2 [ main::b#0 ] zp ZP_WORD:3 [ main::w#0 ]
Uplifting [] best 120 combination
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::b#0 ]
Uplifting [main] best 120 combination zp ZP_BYTE:2 [ main::b#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Tests the sizeof() operator on epressions
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label SCREEN = $400
.const SIZEOF_BYTE = 1
.const SIZEOF_WORD = 2
.const SIZEOF_POINTER = 2
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
jsr main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG8 @end
bend:
//SEG9 main
main: {
.const sz = $f
.label b = 2
.label w = 3
//SEG10 [4] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// Simple types
lda #0
sta b
//SEG11 [5] (word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vwuz1=vbuc1
lda #0
sta w
lda #0
sta w+1
//SEG12 [6] *((const byte*) SCREEN#0) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN
//SEG13 [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN+1
//SEG14 [8] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN+2
//SEG15 [9] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN+3
//SEG16 [10] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5) ← (byte) '0'+(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_WORD
sta SCREEN+5
//SEG17 [11] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) '0'+(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_WORD
sta SCREEN+6
//SEG18 [12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 8) ← (byte) '0'+(const byte) SIZEOF_POINTER -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_POINTER
sta SCREEN+8
//SEG19 [13] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 9) ← (byte) '0'+(const byte) SIZEOF_POINTER -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_POINTER
sta SCREEN+9
//SEG20 [14] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $b) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+3*SIZEOF_BYTE
sta SCREEN+$b
//SEG21 [15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $c) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+3*SIZEOF_WORD
sta SCREEN+$c
//SEG22 [16] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $d) ← (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+(sz+2)*SIZEOF_BYTE
sta SCREEN+$d
//SEG23 [17] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $e) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+4*SIZEOF_BYTE
sta SCREEN+$e
//SEG24 [18] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $f) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+8*SIZEOF_BYTE
sta SCREEN+$f
//SEG25 [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $10) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+$c*SIZEOF_BYTE
sta SCREEN+$10
jmp breturn
//SEG26 main::@return
breturn:
//SEG27 [20] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #'0'+SIZEOF_BYTE
Removing instruction lda #'0'+SIZEOF_BYTE
Removing instruction lda #'0'+SIZEOF_BYTE
Removing instruction lda #'0'+SIZEOF_WORD
Removing instruction lda #'0'+SIZEOF_POINTER
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(const byte) SIZEOF_BYTE SIZEOF_BYTE = (byte/signed byte/word/signed word/dword/signed dword) 1
(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
(void()) main()
(label) main::@return
(byte) main::b
(byte) main::b#0 b zp ZP_BYTE:2 20.0
(byte[3]) main::ba
(byte[main::sz#0+2]) main::bb
(byte[]) main::bc
(byte*) main::bp
(byte) main::idx
(byte[]) main::sa
(byte[]) main::sb
(byte) main::sz
(const byte) main::sz#0 sz = (byte/signed byte/word/signed word/dword/signed dword) $f
(word) main::w
(word) main::w#0 w zp ZP_WORD:3 20.0
(word[3]) main::wa
(word*) main::wp
zp ZP_BYTE:2 [ main::b#0 ]
zp ZP_WORD:3 [ main::w#0 ]
FINAL ASSEMBLER
Score: 91
//SEG0 File Comments
// Tests the sizeof() operator on epressions
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label SCREEN = $400
.const SIZEOF_BYTE = 1
.const SIZEOF_WORD = 2
.const SIZEOF_POINTER = 2
//SEG3 @begin
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
//SEG5 @1
//SEG6 [2] call main
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
//SEG8 @end
//SEG9 main
main: {
.const sz = $f
.label b = 2
.label w = 3
//SEG10 [4] (byte) main::b#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// Simple types
lda #0
sta b
//SEG11 [5] (word) main::w#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vwuz1=vbuc1
sta w
sta w+1
//SEG12 [6] *((const byte*) SCREEN#0) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_BYTE
sta SCREEN
//SEG13 [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
sta SCREEN+1
//SEG14 [8] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
sta SCREEN+2
//SEG15 [9] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) '0'+(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
sta SCREEN+3
//SEG16 [10] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5) ← (byte) '0'+(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_WORD
sta SCREEN+5
//SEG17 [11] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) '0'+(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
sta SCREEN+6
//SEG18 [12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 8) ← (byte) '0'+(const byte) SIZEOF_POINTER -- _deref_pbuc1=vbuc2
lda #'0'+SIZEOF_POINTER
sta SCREEN+8
//SEG19 [13] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 9) ← (byte) '0'+(const byte) SIZEOF_POINTER -- _deref_pbuc1=vbuc2
sta SCREEN+9
//SEG20 [14] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $b) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+3*SIZEOF_BYTE
sta SCREEN+$b
//SEG21 [15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $c) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 3*(const byte) SIZEOF_WORD -- _deref_pbuc1=vbuc2
lda #'0'+3*SIZEOF_WORD
sta SCREEN+$c
//SEG22 [16] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $d) ← (byte) '0'+(const byte) main::sz#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+(sz+2)*SIZEOF_BYTE
sta SCREEN+$d
//SEG23 [17] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $e) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 4*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+4*SIZEOF_BYTE
sta SCREEN+$e
//SEG24 [18] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $f) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) 8*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+8*SIZEOF_BYTE
sta SCREEN+$f
//SEG25 [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $10) ← (byte) '0'+(byte/signed byte/word/signed word/dword/signed dword) $c*(const byte) SIZEOF_BYTE -- _deref_pbuc1=vbuc2
lda #'0'+$c*SIZEOF_BYTE
sta SCREEN+$10
//SEG26 main::@return
//SEG27 [20] return
rts
}

View File

@ -0,0 +1,28 @@
(label) @1
(label) @begin
(label) @end
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(const byte) SIZEOF_BYTE SIZEOF_BYTE = (byte/signed byte/word/signed word/dword/signed dword) 1
(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte/signed byte/word/signed word/dword/signed dword) 2
(void()) main()
(label) main::@return
(byte) main::b
(byte) main::b#0 b zp ZP_BYTE:2 20.0
(byte[3]) main::ba
(byte[main::sz#0+2]) main::bb
(byte[]) main::bc
(byte*) main::bp
(byte) main::idx
(byte[]) main::sa
(byte[]) main::sb
(byte) main::sz
(const byte) main::sz#0 sz = (byte/signed byte/word/signed word/dword/signed dword) $f
(word) main::w
(word) main::w#0 w zp ZP_WORD:3 20.0
(word[3]) main::wa
(word*) main::wp
zp ZP_BYTE:2 [ main::b#0 ]
zp ZP_WORD:3 [ main::w#0 ]