1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-27 04:49:27 +00:00

Added directive reserve($02, $03, $04) for reserving zero page variables to avoid the compiler using them. Directive can be added to functions or globally. Closes #133

This commit is contained in:
jespergravgaard 2019-04-20 01:44:54 +02:00
parent fc79ac187e
commit 1ea5a3af76
39 changed files with 4537 additions and 1580 deletions

View File

@ -63,9 +63,10 @@ public class Program {
private RegisterPotentials registerPotentials;
/** Separation of live range equivalence classes into scopes - used for register uplift */
private RegisterUpliftProgram registerUpliftProgram;
/** Constants identified during pass 1. */
private Collection<VariableRef> earlyIdentifiedConstants;
/** Reserved ZP addresses that the compiler cannot use. */
private List<Number> reservedZps;
public Program() {
this.scope = new ProgramScope();
@ -73,6 +74,7 @@ public class Program {
this.importPaths = new ArrayList<>();
this.imported = new ArrayList<>();
this.asmResourceFiles = new ArrayList<>();
this.reservedZps = new ArrayList<>();
}
public List<Comment> getFileComments() {
@ -280,4 +282,19 @@ public class Program {
return fileName;
}
/**
* Adds a bunch of reserved zero-page addresses that the compiler is not allowed to use.
* @param reservedZp addresses to reserve
*/
public void addReservedZps(List<Number> reservedZp) {
for(Number zp : reservedZp) {
if(!this.reservedZps.contains(zp)) {
this.reservedZps.add(zp);
}
}
}
public List<Number> getReservedZps() {
return reservedZps;
}
}

View File

@ -22,6 +22,8 @@ public class Procedure extends Scope {
private InterruptType interruptType;
/** Comments preceding the procedure in the source code. */
private List<Comment> comments;
/** Reserved zeropage addresses. */
private List<Number> reservedZps;
public Procedure(String name, SymbolType returnType, Scope parentScope) {
super(name, parentScope);
@ -102,6 +104,22 @@ public class Procedure extends Scope {
this.interruptType = interruptType;
}
/**
* Sets any zero-page addresses reserved by the procedure. The KickC-compiler is not allowed to use these addresses.
* @return reserved addresses
*/
public List<Number> getReservedZps() {
return reservedZps;
}
/**
* Gets any reserved zero-page addresses that the compiler is not allowed to use.
* @param reservedZp reserved addresses
*/
public void setReservedZps(List<Number> reservedZps) {
this.reservedZps = reservedZps;
}
/** The different types of supported interrupts. */
public enum InterruptType {
/** Interrupt served by the kernel called through $0314-5. Will exit through the kernel using $ea31. */

View File

@ -25,6 +25,7 @@ decl
: declVariables ';'
| declFunction
| declKasm
| globalDirective
;
declTypes
@ -56,6 +57,10 @@ parameterDecl
| SIMPLETYPE #parameterDeclVoid
;
globalDirective
: directiveReserve ';'
;
directive
: 'const' #directiveConst
| 'extern' #directiveExtern
@ -64,6 +69,11 @@ directive
| 'inline' #directiveInline
| 'volatile' #directiveVolatile
| 'interrupt' ( '(' NAME ')' )? #directiveInterrupt
| directiveReserve #directiveReserveZp
;
directiveReserve
: 'reserve' '(' NUMBER ( ',' NUMBER )* ')'
;
stmtSeq

View File

@ -72,26 +72,27 @@ T__70=71
T__71=72
T__72=73
T__73=74
MNEMONIC=75
KICKASM=76
SIMPLETYPE=77
STRING=78
CHAR=79
BOOLEAN=80
NUMBER=81
NUMFLOAT=82
BINFLOAT=83
DECFLOAT=84
HEXFLOAT=85
NUMINT=86
BININTEGER=87
DECINTEGER=88
HEXINTEGER=89
NAME=90
ASMREL=91
WS=92
COMMENT_LINE=93
COMMENT_BLOCK=94
T__74=75
MNEMONIC=76
KICKASM=77
SIMPLETYPE=78
STRING=79
CHAR=80
BOOLEAN=81
NUMBER=82
NUMFLOAT=83
BINFLOAT=84
DECFLOAT=85
HEXFLOAT=86
NUMINT=87
BININTEGER=88
DECINTEGER=89
HEXINTEGER=90
NAME=91
ASMREL=92
WS=93
COMMENT_LINE=94
COMMENT_BLOCK=95
'import'=1
';'=2
','=3
@ -107,62 +108,63 @@ COMMENT_BLOCK=94
'inline'=13
'volatile'=14
'interrupt'=15
'if'=16
'else'=17
'while'=18
'do'=19
'for'=20
'return'=21
'break'=22
'continue'=23
'asm'=24
':'=25
'..'=26
'signed'=27
'unsigned'=28
'*'=29
'['=30
']'=31
'sizeof'=32
'--'=33
'++'=34
'+'=35
'-'=36
'!'=37
'&'=38
'~'=39
'>>'=40
'<<'=41
'/'=42
'%'=43
'<'=44
'>'=45
'=='=46
'!='=47
'<='=48
'>='=49
'^'=50
'|'=51
'&&'=52
'||'=53
'?'=54
'+='=55
'-='=56
'*='=57
'/='=58
'%='=59
'<<='=60
'>>='=61
'&='=62
'|='=63
'^='=64
'kickasm'=65
'resource'=66
'uses'=67
'clobbers'=68
'bytes'=69
'cycles'=70
'pc'=71
'.byte'=72
'#'=73
'.'=74
'reserve'=16
'if'=17
'else'=18
'while'=19
'do'=20
'for'=21
'return'=22
'break'=23
'continue'=24
'asm'=25
':'=26
'..'=27
'signed'=28
'unsigned'=29
'*'=30
'['=31
']'=32
'sizeof'=33
'--'=34
'++'=35
'+'=36
'-'=37
'!'=38
'&'=39
'~'=40
'>>'=41
'<<'=42
'/'=43
'%'=44
'<'=45
'>'=46
'=='=47
'!='=48
'<='=49
'>='=50
'^'=51
'|'=52
'&&'=53
'||'=54
'?'=55
'+='=56
'-='=57
'*='=58
'/='=59
'%='=60
'<<='=61
'>>='=62
'&='=63
'|='=64
'^='=65
'kickasm'=66
'resource'=67
'uses'=68
'clobbers'=69
'bytes'=70
'cycles'=71
'pc'=72
'.byte'=73
'#'=74
'.'=75

View File

@ -179,6 +179,18 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterGlobalDirective(KickCParser.GlobalDirectiveContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitGlobalDirective(KickCParser.GlobalDirectiveContext ctx) { }
/**
* {@inheritDoc}
*
@ -263,6 +275,30 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveInterrupt(KickCParser.DirectiveInterruptContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveReserve(KickCParser.DirectiveReserveContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveReserve(KickCParser.DirectiveReserveContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -109,6 +109,13 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGlobalDirective(KickCParser.GlobalDirectiveContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@ -158,6 +165,20 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveInterrupt(KickCParser.DirectiveInterruptContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveReserve(KickCParser.DirectiveReserveContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -27,10 +27,10 @@ public class KickCLexer extends Lexer {
T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59,
T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66,
T__66=67, T__67=68, T__68=69, T__69=70, T__70=71, T__71=72, T__72=73,
T__73=74, MNEMONIC=75, KICKASM=76, SIMPLETYPE=77, STRING=78, CHAR=79,
BOOLEAN=80, NUMBER=81, NUMFLOAT=82, BINFLOAT=83, DECFLOAT=84, HEXFLOAT=85,
NUMINT=86, BININTEGER=87, DECINTEGER=88, HEXINTEGER=89, NAME=90, ASMREL=91,
WS=92, COMMENT_LINE=93, COMMENT_BLOCK=94;
T__73=74, T__74=75, MNEMONIC=76, KICKASM=77, SIMPLETYPE=78, STRING=79,
CHAR=80, BOOLEAN=81, NUMBER=82, NUMFLOAT=83, BINFLOAT=84, DECFLOAT=85,
HEXFLOAT=86, NUMINT=87, BININTEGER=88, DECINTEGER=89, HEXINTEGER=90, NAME=91,
ASMREL=92, WS=93, COMMENT_LINE=94, COMMENT_BLOCK=95;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
@ -49,22 +49,23 @@ public class KickCLexer extends Lexer {
"T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56",
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72",
"T__73", "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", "CHAR", "BOOLEAN",
"NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
"DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME",
"NAME_START", "NAME_CHAR", "ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK"
"T__73", "T__74", "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", "CHAR",
"BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT",
"BININTEGER", "DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT",
"NAME", "NAME_START", "NAME_CHAR", "ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK"
};
private static final String[] _LITERAL_NAMES = {
null, "'import'", "';'", "','", "'='", "'('", "')'", "'{'", "'}'", "'const'",
"'extern'", "'align'", "'register'", "'inline'", "'volatile'", "'interrupt'",
"'if'", "'else'", "'while'", "'do'", "'for'", "'return'", "'break'", "'continue'",
"'asm'", "':'", "'..'", "'signed'", "'unsigned'", "'*'", "'['", "']'",
"'sizeof'", "'--'", "'++'", "'+'", "'-'", "'!'", "'&'", "'~'", "'>>'",
"'<<'", "'/'", "'%'", "'<'", "'>'", "'=='", "'!='", "'<='", "'>='", "'^'",
"'|'", "'&&'", "'||'", "'?'", "'+='", "'-='", "'*='", "'/='", "'%='",
"'<<='", "'>>='", "'&='", "'|='", "'^='", "'kickasm'", "'resource'", "'uses'",
"'clobbers'", "'bytes'", "'cycles'", "'pc'", "'.byte'", "'#'", "'.'"
"'reserve'", "'if'", "'else'", "'while'", "'do'", "'for'", "'return'",
"'break'", "'continue'", "'asm'", "':'", "'..'", "'signed'", "'unsigned'",
"'*'", "'['", "']'", "'sizeof'", "'--'", "'++'", "'+'", "'-'", "'!'",
"'&'", "'~'", "'>>'", "'<<'", "'/'", "'%'", "'<'", "'>'", "'=='", "'!='",
"'<='", "'>='", "'^'", "'|'", "'&&'", "'||'", "'?'", "'+='", "'-='", "'*='",
"'/='", "'%='", "'<<='", "'>>='", "'&='", "'|='", "'^='", "'kickasm'",
"'resource'", "'uses'", "'clobbers'", "'bytes'", "'cycles'", "'pc'", "'.byte'",
"'#'", "'.'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
@ -73,10 +74,10 @@ public class KickCLexer extends Lexer {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", "CHAR",
"BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT",
"BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "ASMREL", "WS", "COMMENT_LINE",
"COMMENT_BLOCK"
null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING",
"CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT",
"NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "ASMREL",
"WS", "COMMENT_LINE", "COMMENT_BLOCK"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@ -136,7 +137,7 @@ public class KickCLexer extends Lexer {
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2`\u03c4\b\1\4\2\t"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2a\u03ce\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
@ -147,341 +148,345 @@ public class KickCLexer extends Lexer {
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3"+
"\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\13"+
"\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r"+
"\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17"+
"\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+
"\3\20\3\20\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23"+
"\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26"+
"\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30"+
"\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3\33\3\33\3\33\3\34\3\34"+
"\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35"+
"\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3#\3#\3#\3"+
"$\3$\3%\3%\3&\3&\3\'\3\'\3(\3(\3)\3)\3)\3*\3*\3*\3+\3+\3,\3,\3-\3-\3."+
"\3.\3/\3/\3/\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3"+
"\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67\3\67\38\38\38\39\39\39\3:"+
"\3:\3:\3;\3;\3;\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3@\3@\3@\3A"+
"\3A\3A\3B\3B\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D"+
"\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G\3G\3G"+
"\3H\3H\3H\3I\3I\3I\3I\3I\3I\3J\3J\3K\3K\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L"+
"\3L\3L\3L\3L\3L\5L\u02d3\nL\3M\3M\3M\3M\7M\u02d9\nM\fM\16M\u02dc\13M\3"+
"M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+
"N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\5N\u0306\nN\3O\3O\3"+
"O\3O\7O\u030c\nO\fO\16O\u030f\13O\3O\3O\5O\u0313\nO\3P\3P\3P\3P\5P\u0319"+
"\nP\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\5Q\u0326\nQ\3R\3R\5R\u032a\nR\3S"+
"\3S\3S\5S\u032f\nS\3T\3T\3T\3T\3T\5T\u0336\nT\3T\7T\u0339\nT\fT\16T\u033c"+
"\13T\3T\3T\6T\u0340\nT\rT\16T\u0341\3U\7U\u0345\nU\fU\16U\u0348\13U\3"+
"U\3U\6U\u034c\nU\rU\16U\u034d\3V\3V\3V\3V\3V\5V\u0355\nV\3V\7V\u0358\n"+
"V\fV\16V\u035b\13V\3V\3V\6V\u035f\nV\rV\16V\u0360\3W\3W\3W\5W\u0366\n"+
"W\3X\3X\3X\6X\u036b\nX\rX\16X\u036c\3X\3X\6X\u0371\nX\rX\16X\u0372\5X"+
"\u0375\nX\3Y\6Y\u0378\nY\rY\16Y\u0379\3Z\3Z\3Z\3Z\3Z\5Z\u0381\nZ\3Z\6"+
"Z\u0384\nZ\rZ\16Z\u0385\3[\3[\3\\\3\\\3]\3]\3^\3^\7^\u0390\n^\f^\16^\u0393"+
"\13^\3_\3_\3`\3`\3a\3a\7a\u039b\na\fa\16a\u039e\13a\3a\6a\u03a1\na\ra"+
"\16a\u03a2\3b\6b\u03a6\nb\rb\16b\u03a7\3b\3b\3c\3c\3c\3c\7c\u03b0\nc\f"+
"c\16c\u03b3\13c\3c\3c\3d\3d\3d\3d\7d\u03bb\nd\fd\16d\u03be\13d\3d\3d\3"+
"d\3d\3d\4\u02da\u03bc\2e\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f"+
"\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63"+
"\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62"+
"c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087"+
"E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009b"+
"O\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00af"+
"Y\u00b1Z\u00b3[\u00b5\2\u00b7\2\u00b9\2\u00bb\\\u00bd\2\u00bf\2\u00c1"+
"]\u00c3^\u00c5_\u00c7`\3\2\r\3\2$$\3\2))\4\2DDdd\3\2\62\63\3\2\62;\5\2"+
"\62;CHch\5\2C\\aac|\6\2\62;C\\aac|\4\2--//\6\2\13\f\17\17\"\"\u00a2\u00a2"+
"\4\2\f\f\17\17\2\u0431\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2"+
"\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25"+
"\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2"+
"\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2"+
"\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3"+
"\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2"+
"\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2"+
"Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3"+
"\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2"+
"\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2"+
"w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2"+
"\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b"+
"\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2"+
"\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d"+
"\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2"+
"\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af"+
"\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00bb\3\2\2\2\2\u00c1\3\2\2"+
"\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\3\u00c9\3\2\2\2\5\u00d0"+
"\3\2\2\2\7\u00d2\3\2\2\2\t\u00d4\3\2\2\2\13\u00d6\3\2\2\2\r\u00d8\3\2"+
"\2\2\17\u00da\3\2\2\2\21\u00dc\3\2\2\2\23\u00de\3\2\2\2\25\u00e4\3\2\2"+
"\2\27\u00eb\3\2\2\2\31\u00f1\3\2\2\2\33\u00fa\3\2\2\2\35\u0101\3\2\2\2"+
"\37\u010a\3\2\2\2!\u0114\3\2\2\2#\u0117\3\2\2\2%\u011c\3\2\2\2\'\u0122"+
"\3\2\2\2)\u0125\3\2\2\2+\u0129\3\2\2\2-\u0130\3\2\2\2/\u0136\3\2\2\2\61"+
"\u013f\3\2\2\2\63\u0143\3\2\2\2\65\u0145\3\2\2\2\67\u0148\3\2\2\29\u014f"+
"\3\2\2\2;\u0158\3\2\2\2=\u015a\3\2\2\2?\u015c\3\2\2\2A\u015e\3\2\2\2C"+
"\u0165\3\2\2\2E\u0168\3\2\2\2G\u016b\3\2\2\2I\u016d\3\2\2\2K\u016f\3\2"+
"\2\2M\u0171\3\2\2\2O\u0173\3\2\2\2Q\u0175\3\2\2\2S\u0178\3\2\2\2U\u017b"+
"\3\2\2\2W\u017d\3\2\2\2Y\u017f\3\2\2\2[\u0181\3\2\2\2]\u0183\3\2\2\2_"+
"\u0186\3\2\2\2a\u0189\3\2\2\2c\u018c\3\2\2\2e\u018f\3\2\2\2g\u0191\3\2"+
"\2\2i\u0193\3\2\2\2k\u0196\3\2\2\2m\u0199\3\2\2\2o\u019b\3\2\2\2q\u019e"+
"\3\2\2\2s\u01a1\3\2\2\2u\u01a4\3\2\2\2w\u01a7\3\2\2\2y\u01aa\3\2\2\2{"+
"\u01ae\3\2\2\2}\u01b2\3\2\2\2\177\u01b5\3\2\2\2\u0081\u01b8\3\2\2\2\u0083"+
"\u01bb\3\2\2\2\u0085\u01c3\3\2\2\2\u0087\u01cc\3\2\2\2\u0089\u01d1\3\2"+
"\2\2\u008b\u01da\3\2\2\2\u008d\u01e0\3\2\2\2\u008f\u01e7\3\2\2\2\u0091"+
"\u01ea\3\2\2\2\u0093\u01f0\3\2\2\2\u0095\u01f2\3\2\2\2\u0097\u02d2\3\2"+
"\2\2\u0099\u02d4\3\2\2\2\u009b\u0305\3\2\2\2\u009d\u0307\3\2\2\2\u009f"+
"\u0314\3\2\2\2\u00a1\u0325\3\2\2\2\u00a3\u0329\3\2\2\2\u00a5\u032e\3\2"+
"\2\2\u00a7\u0335\3\2\2\2\u00a9\u0346\3\2\2\2\u00ab\u0354\3\2\2\2\u00ad"+
"\u0365\3\2\2\2\u00af\u0374\3\2\2\2\u00b1\u0377\3\2\2\2\u00b3\u0380\3\2"+
"\2\2\u00b5\u0387\3\2\2\2\u00b7\u0389\3\2\2\2\u00b9\u038b\3\2\2\2\u00bb"+
"\u038d\3\2\2\2\u00bd\u0394\3\2\2\2\u00bf\u0396\3\2\2\2\u00c1\u0398\3\2"+
"\2\2\u00c3\u03a5\3\2\2\2\u00c5\u03ab\3\2\2\2\u00c7\u03b6\3\2\2\2\u00c9"+
"\u00ca\7k\2\2\u00ca\u00cb\7o\2\2\u00cb\u00cc\7r\2\2\u00cc\u00cd\7q\2\2"+
"\u00cd\u00ce\7t\2\2\u00ce\u00cf\7v\2\2\u00cf\4\3\2\2\2\u00d0\u00d1\7="+
"\2\2\u00d1\6\3\2\2\2\u00d2\u00d3\7.\2\2\u00d3\b\3\2\2\2\u00d4\u00d5\7"+
"?\2\2\u00d5\n\3\2\2\2\u00d6\u00d7\7*\2\2\u00d7\f\3\2\2\2\u00d8\u00d9\7"+
"+\2\2\u00d9\16\3\2\2\2\u00da\u00db\7}\2\2\u00db\20\3\2\2\2\u00dc\u00dd"+
"\7\177\2\2\u00dd\22\3\2\2\2\u00de\u00df\7e\2\2\u00df\u00e0\7q\2\2\u00e0"+
"\u00e1\7p\2\2\u00e1\u00e2\7u\2\2\u00e2\u00e3\7v\2\2\u00e3\24\3\2\2\2\u00e4"+
"\u00e5\7g\2\2\u00e5\u00e6\7z\2\2\u00e6\u00e7\7v\2\2\u00e7\u00e8\7g\2\2"+
"\u00e8\u00e9\7t\2\2\u00e9\u00ea\7p\2\2\u00ea\26\3\2\2\2\u00eb\u00ec\7"+
"c\2\2\u00ec\u00ed\7n\2\2\u00ed\u00ee\7k\2\2\u00ee\u00ef\7i\2\2\u00ef\u00f0"+
"\7p\2\2\u00f0\30\3\2\2\2\u00f1\u00f2\7t\2\2\u00f2\u00f3\7g\2\2\u00f3\u00f4"+
"\7i\2\2\u00f4\u00f5\7k\2\2\u00f5\u00f6\7u\2\2\u00f6\u00f7\7v\2\2\u00f7"+
"\u00f8\7g\2\2\u00f8\u00f9\7t\2\2\u00f9\32\3\2\2\2\u00fa\u00fb\7k\2\2\u00fb"+
"\u00fc\7p\2\2\u00fc\u00fd\7n\2\2\u00fd\u00fe\7k\2\2\u00fe\u00ff\7p\2\2"+
"\u00ff\u0100\7g\2\2\u0100\34\3\2\2\2\u0101\u0102\7x\2\2\u0102\u0103\7"+
"q\2\2\u0103\u0104\7n\2\2\u0104\u0105\7c\2\2\u0105\u0106\7v\2\2\u0106\u0107"+
"\7k\2\2\u0107\u0108\7n\2\2\u0108\u0109\7g\2\2\u0109\36\3\2\2\2\u010a\u010b"+
"\7k\2\2\u010b\u010c\7p\2\2\u010c\u010d\7v\2\2\u010d\u010e\7g\2\2\u010e"+
"\u010f\7t\2\2\u010f\u0110\7t\2\2\u0110\u0111\7w\2\2\u0111\u0112\7r\2\2"+
"\u0112\u0113\7v\2\2\u0113 \3\2\2\2\u0114\u0115\7k\2\2\u0115\u0116\7h\2"+
"\2\u0116\"\3\2\2\2\u0117\u0118\7g\2\2\u0118\u0119\7n\2\2\u0119\u011a\7"+
"u\2\2\u011a\u011b\7g\2\2\u011b$\3\2\2\2\u011c\u011d\7y\2\2\u011d\u011e"+
"\7j\2\2\u011e\u011f\7k\2\2\u011f\u0120\7n\2\2\u0120\u0121\7g\2\2\u0121"+
"&\3\2\2\2\u0122\u0123\7f\2\2\u0123\u0124\7q\2\2\u0124(\3\2\2\2\u0125\u0126"+
"\7h\2\2\u0126\u0127\7q\2\2\u0127\u0128\7t\2\2\u0128*\3\2\2\2\u0129\u012a"+
"\7t\2\2\u012a\u012b\7g\2\2\u012b\u012c\7v\2\2\u012c\u012d\7w\2\2\u012d"+
"\u012e\7t\2\2\u012e\u012f\7p\2\2\u012f,\3\2\2\2\u0130\u0131\7d\2\2\u0131"+
"\u0132\7t\2\2\u0132\u0133\7g\2\2\u0133\u0134\7c\2\2\u0134\u0135\7m\2\2"+
"\u0135.\3\2\2\2\u0136\u0137\7e\2\2\u0137\u0138\7q\2\2\u0138\u0139\7p\2"+
"\2\u0139\u013a\7v\2\2\u013a\u013b\7k\2\2\u013b\u013c\7p\2\2\u013c\u013d"+
"\7w\2\2\u013d\u013e\7g\2\2\u013e\60\3\2\2\2\u013f\u0140\7c\2\2\u0140\u0141"+
"\7u\2\2\u0141\u0142\7o\2\2\u0142\62\3\2\2\2\u0143\u0144\7<\2\2\u0144\64"+
"\3\2\2\2\u0145\u0146\7\60\2\2\u0146\u0147\7\60\2\2\u0147\66\3\2\2\2\u0148"+
"\u0149\7u\2\2\u0149\u014a\7k\2\2\u014a\u014b\7i\2\2\u014b\u014c\7p\2\2"+
"\u014c\u014d\7g\2\2\u014d\u014e\7f\2\2\u014e8\3\2\2\2\u014f\u0150\7w\2"+
"\2\u0150\u0151\7p\2\2\u0151\u0152\7u\2\2\u0152\u0153\7k\2\2\u0153\u0154"+
"\7i\2\2\u0154\u0155\7p\2\2\u0155\u0156\7g\2\2\u0156\u0157\7f\2\2\u0157"+
":\3\2\2\2\u0158\u0159\7,\2\2\u0159<\3\2\2\2\u015a\u015b\7]\2\2\u015b>"+
"\3\2\2\2\u015c\u015d\7_\2\2\u015d@\3\2\2\2\u015e\u015f\7u\2\2\u015f\u0160"+
"\7k\2\2\u0160\u0161\7|\2\2\u0161\u0162\7g\2\2\u0162\u0163\7q\2\2\u0163"+
"\u0164\7h\2\2\u0164B\3\2\2\2\u0165\u0166\7/\2\2\u0166\u0167\7/\2\2\u0167"+
"D\3\2\2\2\u0168\u0169\7-\2\2\u0169\u016a\7-\2\2\u016aF\3\2\2\2\u016b\u016c"+
"\7-\2\2\u016cH\3\2\2\2\u016d\u016e\7/\2\2\u016eJ\3\2\2\2\u016f\u0170\7"+
"#\2\2\u0170L\3\2\2\2\u0171\u0172\7(\2\2\u0172N\3\2\2\2\u0173\u0174\7\u0080"+
"\2\2\u0174P\3\2\2\2\u0175\u0176\7@\2\2\u0176\u0177\7@\2\2\u0177R\3\2\2"+
"\2\u0178\u0179\7>\2\2\u0179\u017a\7>\2\2\u017aT\3\2\2\2\u017b\u017c\7"+
"\61\2\2\u017cV\3\2\2\2\u017d\u017e\7\'\2\2\u017eX\3\2\2\2\u017f\u0180"+
"\7>\2\2\u0180Z\3\2\2\2\u0181\u0182\7@\2\2\u0182\\\3\2\2\2\u0183\u0184"+
"\7?\2\2\u0184\u0185\7?\2\2\u0185^\3\2\2\2\u0186\u0187\7#\2\2\u0187\u0188"+
"\7?\2\2\u0188`\3\2\2\2\u0189\u018a\7>\2\2\u018a\u018b\7?\2\2\u018bb\3"+
"\2\2\2\u018c\u018d\7@\2\2\u018d\u018e\7?\2\2\u018ed\3\2\2\2\u018f\u0190"+
"\7`\2\2\u0190f\3\2\2\2\u0191\u0192\7~\2\2\u0192h\3\2\2\2\u0193\u0194\7"+
"(\2\2\u0194\u0195\7(\2\2\u0195j\3\2\2\2\u0196\u0197\7~\2\2\u0197\u0198"+
"\7~\2\2\u0198l\3\2\2\2\u0199\u019a\7A\2\2\u019an\3\2\2\2\u019b\u019c\7"+
"-\2\2\u019c\u019d\7?\2\2\u019dp\3\2\2\2\u019e\u019f\7/\2\2\u019f\u01a0"+
"\7?\2\2\u01a0r\3\2\2\2\u01a1\u01a2\7,\2\2\u01a2\u01a3\7?\2\2\u01a3t\3"+
"\2\2\2\u01a4\u01a5\7\61\2\2\u01a5\u01a6\7?\2\2\u01a6v\3\2\2\2\u01a7\u01a8"+
"\7\'\2\2\u01a8\u01a9\7?\2\2\u01a9x\3\2\2\2\u01aa\u01ab\7>\2\2\u01ab\u01ac"+
"\7>\2\2\u01ac\u01ad\7?\2\2\u01adz\3\2\2\2\u01ae\u01af\7@\2\2\u01af\u01b0"+
"\7@\2\2\u01b0\u01b1\7?\2\2\u01b1|\3\2\2\2\u01b2\u01b3\7(\2\2\u01b3\u01b4"+
"\7?\2\2\u01b4~\3\2\2\2\u01b5\u01b6\7~\2\2\u01b6\u01b7\7?\2\2\u01b7\u0080"+
"\3\2\2\2\u01b8\u01b9\7`\2\2\u01b9\u01ba\7?\2\2\u01ba\u0082\3\2\2\2\u01bb"+
"\u01bc\7m\2\2\u01bc\u01bd\7k\2\2\u01bd\u01be\7e\2\2\u01be\u01bf\7m\2\2"+
"\u01bf\u01c0\7c\2\2\u01c0\u01c1\7u\2\2\u01c1\u01c2\7o\2\2\u01c2\u0084"+
"\3\2\2\2\u01c3\u01c4\7t\2\2\u01c4\u01c5\7g\2\2\u01c5\u01c6\7u\2\2\u01c6"+
"\u01c7\7q\2\2\u01c7\u01c8\7w\2\2\u01c8\u01c9\7t\2\2\u01c9\u01ca\7e\2\2"+
"\u01ca\u01cb\7g\2\2\u01cb\u0086\3\2\2\2\u01cc\u01cd\7w\2\2\u01cd\u01ce"+
"\7u\2\2\u01ce\u01cf\7g\2\2\u01cf\u01d0\7u\2\2\u01d0\u0088\3\2\2\2\u01d1"+
"\u01d2\7e\2\2\u01d2\u01d3\7n\2\2\u01d3\u01d4\7q\2\2\u01d4\u01d5\7d\2\2"+
"\u01d5\u01d6\7d\2\2\u01d6\u01d7\7g\2\2\u01d7\u01d8\7t\2\2\u01d8\u01d9"+
"\7u\2\2\u01d9\u008a\3\2\2\2\u01da\u01db\7d\2\2\u01db\u01dc\7{\2\2\u01dc"+
"\u01dd\7v\2\2\u01dd\u01de\7g\2\2\u01de\u01df\7u\2\2\u01df\u008c\3\2\2"+
"\2\u01e0\u01e1\7e\2\2\u01e1\u01e2\7{\2\2\u01e2\u01e3\7e\2\2\u01e3\u01e4"+
"\7n\2\2\u01e4\u01e5\7g\2\2\u01e5\u01e6\7u\2\2\u01e6\u008e\3\2\2\2\u01e7"+
"\u01e8\7r\2\2\u01e8\u01e9\7e\2\2\u01e9\u0090\3\2\2\2\u01ea\u01eb\7\60"+
"\2\2\u01eb\u01ec\7d\2\2\u01ec\u01ed\7{\2\2\u01ed\u01ee\7v\2\2\u01ee\u01ef"+
"\7g\2\2\u01ef\u0092\3\2\2\2\u01f0\u01f1\7%\2\2\u01f1\u0094\3\2\2\2\u01f2"+
"\u01f3\7\60\2\2\u01f3\u0096\3\2\2\2\u01f4\u01f5\7d\2\2\u01f5\u01f6\7t"+
"\2\2\u01f6\u02d3\7m\2\2\u01f7\u01f8\7q\2\2\u01f8\u01f9\7t\2\2\u01f9\u02d3"+
"\7c\2\2\u01fa\u01fb\7m\2\2\u01fb\u01fc\7k\2\2\u01fc\u02d3\7n\2\2\u01fd"+
"\u01fe\7u\2\2\u01fe\u01ff\7n\2\2\u01ff\u02d3\7q\2\2\u0200\u0201\7p\2\2"+
"\u0201\u0202\7q\2\2\u0202\u02d3\7r\2\2\u0203\u0204\7c\2\2\u0204\u0205"+
"\7u\2\2\u0205\u02d3\7n\2\2\u0206\u0207\7r\2\2\u0207\u0208\7j\2\2\u0208"+
"\u02d3\7r\2\2\u0209\u020a\7c\2\2\u020a\u020b\7p\2\2\u020b\u02d3\7e\2\2"+
"\u020c\u020d\7d\2\2\u020d\u020e\7r\2\2\u020e\u02d3\7n\2\2\u020f\u0210"+
"\7e\2\2\u0210\u0211\7n\2\2\u0211\u02d3\7e\2\2\u0212\u0213\7l\2\2\u0213"+
"\u0214\7u\2\2\u0214\u02d3\7t\2\2\u0215\u0216\7c\2\2\u0216\u0217\7p\2\2"+
"\u0217\u02d3\7f\2\2\u0218\u0219\7t\2\2\u0219\u021a\7n\2\2\u021a\u02d3"+
"\7c\2\2\u021b\u021c\7d\2\2\u021c\u021d\7k\2\2\u021d\u02d3\7v\2\2\u021e"+
"\u021f\7t\2\2\u021f\u0220\7q\2\2\u0220\u02d3\7n\2\2\u0221\u0222\7r\2\2"+
"\u0222\u0223\7n\2\2\u0223\u02d3\7c\2\2\u0224\u0225\7r\2\2\u0225\u0226"+
"\7n\2\2\u0226\u02d3\7r\2\2\u0227\u0228\7d\2\2\u0228\u0229\7o\2\2\u0229"+
"\u02d3\7k\2\2\u022a\u022b\7u\2\2\u022b\u022c\7g\2\2\u022c\u02d3\7e\2\2"+
"\u022d\u022e\7t\2\2\u022e\u022f\7v\2\2\u022f\u02d3\7k\2\2\u0230\u0231"+
"\7g\2\2\u0231\u0232\7q\2\2\u0232\u02d3\7t\2\2\u0233\u0234\7u\2\2\u0234"+
"\u0235\7t\2\2\u0235\u02d3\7g\2\2\u0236\u0237\7n\2\2\u0237\u0238\7u\2\2"+
"\u0238\u02d3\7t\2\2\u0239\u023a\7r\2\2\u023a\u023b\7j\2\2\u023b\u02d3"+
"\7c\2\2\u023c\u023d\7c\2\2\u023d\u023e\7n\2\2\u023e\u02d3\7t\2\2\u023f"+
"\u0240\7l\2\2\u0240\u0241\7o\2\2\u0241\u02d3\7r\2\2\u0242\u0243\7d\2\2"+
"\u0243\u0244\7x\2\2\u0244\u02d3\7e\2\2\u0245\u0246\7e\2\2\u0246\u0247"+
"\7n\2\2\u0247\u02d3\7k\2\2\u0248\u0249\7t\2\2\u0249\u024a\7v\2\2\u024a"+
"\u02d3\7u\2\2\u024b\u024c\7c\2\2\u024c\u024d\7f\2\2\u024d\u02d3\7e\2\2"+
"\u024e\u024f\7t\2\2\u024f\u0250\7t\2\2\u0250\u02d3\7c\2\2\u0251\u0252"+
"\7d\2\2\u0252\u0253\7x\2\2\u0253\u02d3\7u\2\2\u0254\u0255\7u\2\2\u0255"+
"\u0256\7g\2\2\u0256\u02d3\7k\2\2\u0257\u0258\7u\2\2\u0258\u0259\7c\2\2"+
"\u0259\u02d3\7z\2\2\u025a\u025b\7u\2\2\u025b\u025c\7v\2\2\u025c\u02d3"+
"\7{\2\2\u025d\u025e\7u\2\2\u025e\u025f\7v\2\2\u025f\u02d3\7c\2\2\u0260"+
"\u0261\7u\2\2\u0261\u0262\7v\2\2\u0262\u02d3\7z\2\2\u0263\u0264\7f\2\2"+
"\u0264\u0265\7g\2\2\u0265\u02d3\7{\2\2\u0266\u0267\7v\2\2\u0267\u0268"+
"\7z\2\2\u0268\u02d3\7c\2\2\u0269\u026a\7z\2\2\u026a\u026b\7c\2\2\u026b"+
"\u02d3\7c\2\2\u026c\u026d\7d\2\2\u026d\u026e\7e\2\2\u026e\u02d3\7e\2\2"+
"\u026f\u0270\7c\2\2\u0270\u0271\7j\2\2\u0271\u02d3\7z\2\2\u0272\u0273"+
"\7v\2\2\u0273\u0274\7{\2\2\u0274\u02d3\7c\2\2\u0275\u0276\7v\2\2\u0276"+
"\u0277\7z\2\2\u0277\u02d3\7u\2\2\u0278\u0279\7v\2\2\u0279\u027a\7c\2\2"+
"\u027a\u02d3\7u\2\2\u027b\u027c\7u\2\2\u027c\u027d\7j\2\2\u027d\u02d3"+
"\7{\2\2\u027e\u027f\7u\2\2\u027f\u0280\7j\2\2\u0280\u02d3\7z\2\2\u0281"+
"\u0282\7n\2\2\u0282\u0283\7f\2\2\u0283\u02d3\7{\2\2\u0284\u0285\7n\2\2"+
"\u0285\u0286\7f\2\2\u0286\u02d3\7c\2\2\u0287\u0288\7n\2\2\u0288\u0289"+
"\7f\2\2\u0289\u02d3\7z\2\2\u028a\u028b\7n\2\2\u028b\u028c\7c\2\2\u028c"+
"\u02d3\7z\2\2\u028d\u028e\7v\2\2\u028e\u028f\7c\2\2\u028f\u02d3\7{\2\2"+
"\u0290\u0291\7v\2\2\u0291\u0292\7c\2\2\u0292\u02d3\7z\2\2\u0293\u0294"+
"\7d\2\2\u0294\u0295\7e\2\2\u0295\u02d3\7u\2\2\u0296\u0297\7e\2\2\u0297"+
"\u0298\7n\2\2\u0298\u02d3\7x\2\2\u0299\u029a\7v\2\2\u029a\u029b\7u\2\2"+
"\u029b\u02d3\7z\2\2\u029c\u029d\7n\2\2\u029d\u029e\7c\2\2\u029e\u02d3"+
"\7u\2\2\u029f\u02a0\7e\2\2\u02a0\u02a1\7r\2\2\u02a1\u02d3\7{\2\2\u02a2"+
"\u02a3\7e\2\2\u02a3\u02a4\7o\2\2\u02a4\u02d3\7r\2\2\u02a5\u02a6\7e\2\2"+
"\u02a6\u02a7\7r\2\2\u02a7\u02d3\7z\2\2\u02a8\u02a9\7f\2\2\u02a9\u02aa"+
"\7e\2\2\u02aa\u02d3\7r\2\2\u02ab\u02ac\7f\2\2\u02ac\u02ad\7g\2\2\u02ad"+
"\u02d3\7e\2\2\u02ae\u02af\7k\2\2\u02af\u02b0\7p\2\2\u02b0\u02d3\7e\2\2"+
"\u02b1\u02b2\7c\2\2\u02b2\u02b3\7z\2\2\u02b3\u02d3\7u\2\2\u02b4\u02b5"+
"\7d\2\2\u02b5\u02b6\7p\2\2\u02b6\u02d3\7g\2\2\u02b7\u02b8\7e\2\2\u02b8"+
"\u02b9\7n\2\2\u02b9\u02d3\7f\2\2\u02ba\u02bb\7u\2\2\u02bb\u02bc\7d\2\2"+
"\u02bc\u02d3\7e\2\2\u02bd\u02be\7k\2\2\u02be\u02bf\7u\2\2\u02bf\u02d3"+
"\7e\2\2\u02c0\u02c1\7k\2\2\u02c1\u02c2\7p\2\2\u02c2\u02d3\7z\2\2\u02c3"+
"\u02c4\7d\2\2\u02c4\u02c5\7g\2\2\u02c5\u02d3\7s\2\2\u02c6\u02c7\7u\2\2"+
"\u02c7\u02c8\7g\2\2\u02c8\u02d3\7f\2\2\u02c9\u02ca\7f\2\2\u02ca\u02cb"+
"\7g\2\2\u02cb\u02d3\7z\2\2\u02cc\u02cd\7k\2\2\u02cd\u02ce\7p\2\2\u02ce"+
"\u02d3\7{\2\2\u02cf\u02d0\7t\2\2\u02d0\u02d1\7q\2\2\u02d1\u02d3\7t\2\2"+
"\u02d2\u01f4\3\2\2\2\u02d2\u01f7\3\2\2\2\u02d2\u01fa\3\2\2\2\u02d2\u01fd"+
"\3\2\2\2\u02d2\u0200\3\2\2\2\u02d2\u0203\3\2\2\2\u02d2\u0206\3\2\2\2\u02d2"+
"\u0209\3\2\2\2\u02d2\u020c\3\2\2\2\u02d2\u020f\3\2\2\2\u02d2\u0212\3\2"+
"\2\2\u02d2\u0215\3\2\2\2\u02d2\u0218\3\2\2\2\u02d2\u021b\3\2\2\2\u02d2"+
"\u021e\3\2\2\2\u02d2\u0221\3\2\2\2\u02d2\u0224\3\2\2\2\u02d2\u0227\3\2"+
"\2\2\u02d2\u022a\3\2\2\2\u02d2\u022d\3\2\2\2\u02d2\u0230\3\2\2\2\u02d2"+
"\u0233\3\2\2\2\u02d2\u0236\3\2\2\2\u02d2\u0239\3\2\2\2\u02d2\u023c\3\2"+
"\2\2\u02d2\u023f\3\2\2\2\u02d2\u0242\3\2\2\2\u02d2\u0245\3\2\2\2\u02d2"+
"\u0248\3\2\2\2\u02d2\u024b\3\2\2\2\u02d2\u024e\3\2\2\2\u02d2\u0251\3\2"+
"\2\2\u02d2\u0254\3\2\2\2\u02d2\u0257\3\2\2\2\u02d2\u025a\3\2\2\2\u02d2"+
"\u025d\3\2\2\2\u02d2\u0260\3\2\2\2\u02d2\u0263\3\2\2\2\u02d2\u0266\3\2"+
"\2\2\u02d2\u0269\3\2\2\2\u02d2\u026c\3\2\2\2\u02d2\u026f\3\2\2\2\u02d2"+
"\u0272\3\2\2\2\u02d2\u0275\3\2\2\2\u02d2\u0278\3\2\2\2\u02d2\u027b\3\2"+
"\2\2\u02d2\u027e\3\2\2\2\u02d2\u0281\3\2\2\2\u02d2\u0284\3\2\2\2\u02d2"+
"\u0287\3\2\2\2\u02d2\u028a\3\2\2\2\u02d2\u028d\3\2\2\2\u02d2\u0290\3\2"+
"\2\2\u02d2\u0293\3\2\2\2\u02d2\u0296\3\2\2\2\u02d2\u0299\3\2\2\2\u02d2"+
"\u029c\3\2\2\2\u02d2\u029f\3\2\2\2\u02d2\u02a2\3\2\2\2\u02d2\u02a5\3\2"+
"\2\2\u02d2\u02a8\3\2\2\2\u02d2\u02ab\3\2\2\2\u02d2\u02ae\3\2\2\2\u02d2"+
"\u02b1\3\2\2\2\u02d2\u02b4\3\2\2\2\u02d2\u02b7\3\2\2\2\u02d2\u02ba\3\2"+
"\2\2\u02d2\u02bd\3\2\2\2\u02d2\u02c0\3\2\2\2\u02d2\u02c3\3\2\2\2\u02d2"+
"\u02c6\3\2\2\2\u02d2\u02c9\3\2\2\2\u02d2\u02cc\3\2\2\2\u02d2\u02cf\3\2"+
"\2\2\u02d3\u0098\3\2\2\2\u02d4\u02d5\7}\2\2\u02d5\u02d6\7}\2\2\u02d6\u02da"+
"\3\2\2\2\u02d7\u02d9\13\2\2\2\u02d8\u02d7\3\2\2\2\u02d9\u02dc\3\2\2\2"+
"\u02da\u02db\3\2\2\2\u02da\u02d8\3\2\2\2\u02db\u02dd\3\2\2\2\u02dc\u02da"+
"\3\2\2\2\u02dd\u02de\7\177\2\2\u02de\u02df\7\177\2\2\u02df\u009a\3\2\2"+
"\2\u02e0\u02e1\7d\2\2\u02e1\u02e2\7{\2\2\u02e2\u02e3\7v\2\2\u02e3\u0306"+
"\7g\2\2\u02e4\u02e5\7y\2\2\u02e5\u02e6\7q\2\2\u02e6\u02e7\7t\2\2\u02e7"+
"\u0306\7f\2\2\u02e8\u02e9\7f\2\2\u02e9\u02ea\7y\2\2\u02ea\u02eb\7q\2\2"+
"\u02eb\u02ec\7t\2\2\u02ec\u0306\7f\2\2\u02ed\u02ee\7d\2\2\u02ee\u02ef"+
"\7q\2\2\u02ef\u02f0\7q\2\2\u02f0\u0306\7n\2\2\u02f1\u02f2\7e\2\2\u02f2"+
"\u02f3\7j\2\2\u02f3\u02f4\7c\2\2\u02f4\u0306\7t\2\2\u02f5\u02f6\7u\2\2"+
"\u02f6\u02f7\7j\2\2\u02f7\u02f8\7q\2\2\u02f8\u02f9\7t\2\2\u02f9\u0306"+
"\7v\2\2\u02fa\u02fb\7k\2\2\u02fb\u02fc\7p\2\2\u02fc\u0306\7v\2\2\u02fd"+
"\u02fe\7n\2\2\u02fe\u02ff\7q\2\2\u02ff\u0300\7p\2\2\u0300\u0306\7i\2\2"+
"\u0301\u0302\7x\2\2\u0302\u0303\7q\2\2\u0303\u0304\7k\2\2\u0304\u0306"+
"\7f\2\2\u0305\u02e0\3\2\2\2\u0305\u02e4\3\2\2\2\u0305\u02e8\3\2\2\2\u0305"+
"\u02ed\3\2\2\2\u0305\u02f1\3\2\2\2\u0305\u02f5\3\2\2\2\u0305\u02fa\3\2"+
"\2\2\u0305\u02fd\3\2\2\2\u0305\u0301\3\2\2\2\u0306\u009c\3\2\2\2\u0307"+
"\u030d\7$\2\2\u0308\u0309\7^\2\2\u0309\u030c\7$\2\2\u030a\u030c\n\2\2"+
"\2\u030b\u0308\3\2\2\2\u030b\u030a\3\2\2\2\u030c\u030f\3\2\2\2\u030d\u030b"+
"\3\2\2\2\u030d\u030e\3\2\2\2\u030e\u0310\3\2\2\2\u030f\u030d\3\2\2\2\u0310"+
"\u0312\7$\2\2\u0311\u0313\7|\2\2\u0312\u0311\3\2\2\2\u0312\u0313\3\2\2"+
"\2\u0313\u009e\3\2\2\2\u0314\u0318\7)\2\2\u0315\u0316\7^\2\2\u0316\u0319"+
"\7)\2\2\u0317\u0319\n\3\2\2\u0318\u0315\3\2\2\2\u0318\u0317\3\2\2\2\u0319"+
"\u031a\3\2\2\2\u031a\u031b\7)\2\2\u031b\u00a0\3\2\2\2\u031c\u031d\7v\2"+
"\2\u031d\u031e\7t\2\2\u031e\u031f\7w\2\2\u031f\u0326\7g\2\2\u0320\u0321"+
"\7h\2\2\u0321\u0322\7c\2\2\u0322\u0323\7n\2\2\u0323\u0324\7u\2\2\u0324"+
"\u0326\7g\2\2\u0325\u031c\3\2\2\2\u0325\u0320\3\2\2\2\u0326\u00a2\3\2"+
"\2\2\u0327\u032a\5\u00a5S\2\u0328\u032a\5\u00adW\2\u0329\u0327\3\2\2\2"+
"\u0329\u0328\3\2\2\2\u032a\u00a4\3\2\2\2\u032b\u032f\5\u00a7T\2\u032c"+
"\u032f\5\u00a9U\2\u032d\u032f\5\u00abV\2\u032e\u032b\3\2\2\2\u032e\u032c"+
"\3\2\2\2\u032e\u032d\3\2\2\2\u032f\u00a6\3\2\2\2\u0330\u0336\7\'\2\2\u0331"+
"\u0332\7\62\2\2\u0332\u0336\7d\2\2\u0333\u0334\7\62\2\2\u0334\u0336\7"+
"D\2\2\u0335\u0330\3\2\2\2\u0335\u0331\3\2\2\2\u0335\u0333\3\2\2\2\u0336"+
"\u033a\3\2\2\2\u0337\u0339\5\u00b5[\2\u0338\u0337\3\2\2\2\u0339\u033c"+
"\3\2\2\2\u033a\u0338\3\2\2\2\u033a\u033b\3\2\2\2\u033b\u033d\3\2\2\2\u033c"+
"\u033a\3\2\2\2\u033d\u033f\7\60\2\2\u033e\u0340\5\u00b5[\2\u033f\u033e"+
"\3\2\2\2\u0340\u0341\3\2\2\2\u0341\u033f\3\2\2\2\u0341\u0342\3\2\2\2\u0342"+
"\u00a8\3\2\2\2\u0343\u0345\5\u00b7\\\2\u0344\u0343\3\2\2\2\u0345\u0348"+
"\3\2\2\2\u0346\u0344\3\2\2\2\u0346\u0347\3\2\2\2\u0347\u0349\3\2\2\2\u0348"+
"\u0346\3\2\2\2\u0349\u034b\7\60\2\2\u034a\u034c\5\u00b7\\\2\u034b\u034a"+
"\3\2\2\2\u034c\u034d\3\2\2\2\u034d\u034b\3\2\2\2\u034d\u034e\3\2\2\2\u034e"+
"\u00aa\3\2\2\2\u034f\u0355\7&\2\2\u0350\u0351\7\62\2\2\u0351\u0355\7z"+
"\2\2\u0352\u0353\7\62\2\2\u0353\u0355\7Z\2\2\u0354\u034f\3\2\2\2\u0354"+
"\u0350\3\2\2\2\u0354\u0352\3\2\2\2\u0355\u0359\3\2\2\2\u0356\u0358\5\u00b9"+
"]\2\u0357\u0356\3\2\2\2\u0358\u035b\3\2\2\2\u0359\u0357\3\2\2\2\u0359"+
"\u035a\3\2\2\2\u035a\u035c\3\2\2\2\u035b\u0359\3\2\2\2\u035c\u035e\7\60"+
"\2\2\u035d\u035f\5\u00b9]\2\u035e\u035d\3\2\2\2\u035f\u0360\3\2\2\2\u0360"+
"\u035e\3\2\2\2\u0360\u0361\3\2\2\2\u0361\u00ac\3\2\2\2\u0362\u0366\5\u00b1"+
"Y\2\u0363\u0366\5\u00b3Z\2\u0364\u0366\5\u00afX\2\u0365\u0362\3\2\2\2"+
"\u0365\u0363\3\2\2\2\u0365\u0364\3\2\2\2\u0366\u00ae\3\2\2\2\u0367\u0368"+
"\7\62\2\2\u0368\u036a\t\4\2\2\u0369\u036b\5\u00b5[\2\u036a\u0369\3\2\2"+
"\2\u036b\u036c\3\2\2\2\u036c\u036a\3\2\2\2\u036c\u036d\3\2\2\2\u036d\u0375"+
"\3\2\2\2\u036e\u0370\7\'\2\2\u036f\u0371\5\u00b5[\2\u0370\u036f\3\2\2"+
"\2\u0371\u0372\3\2\2\2\u0372\u0370\3\2\2\2\u0372\u0373\3\2\2\2\u0373\u0375"+
"\3\2\2\2\u0374\u0367\3\2\2\2\u0374\u036e\3\2\2\2\u0375\u00b0\3\2\2\2\u0376"+
"\u0378\5\u00b7\\\2\u0377\u0376\3\2\2\2\u0378\u0379\3\2\2\2\u0379\u0377"+
"\3\2\2\2\u0379\u037a\3\2\2\2\u037a\u00b2\3\2\2\2\u037b\u0381\7&\2\2\u037c"+
"\u037d\7\62\2\2\u037d\u0381\7z\2\2\u037e\u037f\7\62\2\2\u037f\u0381\7"+
"Z\2\2\u0380\u037b\3\2\2\2\u0380\u037c\3\2\2\2\u0380\u037e\3\2\2\2\u0381"+
"\u0383\3\2\2\2\u0382\u0384\5\u00b9]\2\u0383\u0382\3\2\2\2\u0384\u0385"+
"\3\2\2\2\u0385\u0383\3\2\2\2\u0385\u0386\3\2\2\2\u0386\u00b4\3\2\2\2\u0387"+
"\u0388\t\5\2\2\u0388\u00b6\3\2\2\2\u0389\u038a\t\6\2\2\u038a\u00b8\3\2"+
"\2\2\u038b\u038c\t\7\2\2\u038c\u00ba\3\2\2\2\u038d\u0391\5\u00bd_\2\u038e"+
"\u0390\5\u00bf`\2\u038f\u038e\3\2\2\2\u0390\u0393\3\2\2\2\u0391\u038f"+
"\3\2\2\2\u0391\u0392\3\2\2\2\u0392\u00bc\3\2\2\2\u0393\u0391\3\2\2\2\u0394"+
"\u0395\t\b\2\2\u0395\u00be\3\2\2\2\u0396\u0397\t\t\2\2\u0397\u00c0\3\2"+
"\2\2\u0398\u039c\7#\2\2\u0399\u039b\5\u00bf`\2\u039a\u0399\3\2\2\2\u039b"+
"\u039e\3\2\2\2\u039c\u039a\3\2\2\2\u039c\u039d\3\2\2\2\u039d\u03a0\3\2"+
"\2\2\u039e\u039c\3\2\2\2\u039f\u03a1\t\n\2\2\u03a0\u039f\3\2\2\2\u03a1"+
"\u03a2\3\2\2\2\u03a2\u03a0\3\2\2\2\u03a2\u03a3\3\2\2\2\u03a3\u00c2\3\2"+
"\2\2\u03a4\u03a6\t\13\2\2\u03a5\u03a4\3\2\2\2\u03a6\u03a7\3\2\2\2\u03a7"+
"\u03a5\3\2\2\2\u03a7\u03a8\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9\u03aa\bb"+
"\2\2\u03aa\u00c4\3\2\2\2\u03ab\u03ac\7\61\2\2\u03ac\u03ad\7\61\2\2\u03ad"+
"\u03b1\3\2\2\2\u03ae\u03b0\n\f\2\2\u03af\u03ae\3\2\2\2\u03b0\u03b3\3\2"+
"\2\2\u03b1\u03af\3\2\2\2\u03b1\u03b2\3\2\2\2\u03b2\u03b4\3\2\2\2\u03b3"+
"\u03b1\3\2\2\2\u03b4\u03b5\bc\3\2\u03b5\u00c6\3\2\2\2\u03b6\u03b7\7\61"+
"\2\2\u03b7\u03b8\7,\2\2\u03b8\u03bc\3\2\2\2\u03b9\u03bb\13\2\2\2\u03ba"+
"\u03b9\3\2\2\2\u03bb\u03be\3\2\2\2\u03bc\u03bd\3\2\2\2\u03bc\u03ba\3\2"+
"\2\2\u03bd\u03bf\3\2\2\2\u03be\u03bc\3\2\2\2\u03bf\u03c0\7,\2\2\u03c0"+
"\u03c1\7\61\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c3\bd\3\2\u03c3\u00c8\3\2"+
"\2\2\"\2\u02d2\u02da\u0305\u030b\u030d\u0312\u0318\u0325\u0329\u032e\u0335"+
"\u033a\u0341\u0346\u034d\u0354\u0359\u0360\u0365\u036c\u0372\u0374\u0379"+
"\u0380\u0385\u0391\u039c\u03a2\u03a7\u03b1\u03bc\4\2\3\2\2\4\2";
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3"+
"\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3"+
"\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r"+
"\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3"+
"\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3"+
"\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+
"\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3"+
"\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3"+
"\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\32\3"+
"\32\3\32\3\32\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3"+
"\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3 \3 \3!\3"+
"!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3%\3%\3&\3&\3\'\3\'\3"+
"(\3(\3)\3)\3*\3*\3*\3+\3+\3+\3,\3,\3-\3-\3.\3.\3/\3/\3\60\3\60\3\60\3"+
"\61\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3\65\3\65\3\66\3"+
"\66\3\66\3\67\3\67\3\67\38\38\39\39\39\3:\3:\3:\3;\3;\3;\3<\3<\3<\3=\3"+
"=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3C\3"+
"C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3"+
"F\3F\3F\3F\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3J\3J\3J\3"+
"J\3J\3J\3K\3K\3L\3L\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3"+
"M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\5M\u02dd"+
"\nM\3N\3N\3N\3N\7N\u02e3\nN\fN\16N\u02e6\13N\3N\3N\3N\3O\3O\3O\3O\3O\3"+
"O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3"+
"O\3O\3O\3O\3O\3O\3O\3O\3O\5O\u0310\nO\3P\3P\3P\3P\7P\u0316\nP\fP\16P\u0319"+
"\13P\3P\3P\5P\u031d\nP\3Q\3Q\3Q\3Q\5Q\u0323\nQ\3Q\3Q\3R\3R\3R\3R\3R\3"+
"R\3R\3R\3R\5R\u0330\nR\3S\3S\5S\u0334\nS\3T\3T\3T\5T\u0339\nT\3U\3U\3"+
"U\3U\3U\5U\u0340\nU\3U\7U\u0343\nU\fU\16U\u0346\13U\3U\3U\6U\u034a\nU"+
"\rU\16U\u034b\3V\7V\u034f\nV\fV\16V\u0352\13V\3V\3V\6V\u0356\nV\rV\16"+
"V\u0357\3W\3W\3W\3W\3W\5W\u035f\nW\3W\7W\u0362\nW\fW\16W\u0365\13W\3W"+
"\3W\6W\u0369\nW\rW\16W\u036a\3X\3X\3X\5X\u0370\nX\3Y\3Y\3Y\6Y\u0375\n"+
"Y\rY\16Y\u0376\3Y\3Y\6Y\u037b\nY\rY\16Y\u037c\5Y\u037f\nY\3Z\6Z\u0382"+
"\nZ\rZ\16Z\u0383\3[\3[\3[\3[\3[\5[\u038b\n[\3[\6[\u038e\n[\r[\16[\u038f"+
"\3\\\3\\\3]\3]\3^\3^\3_\3_\7_\u039a\n_\f_\16_\u039d\13_\3`\3`\3a\3a\3"+
"b\3b\7b\u03a5\nb\fb\16b\u03a8\13b\3b\6b\u03ab\nb\rb\16b\u03ac\3c\6c\u03b0"+
"\nc\rc\16c\u03b1\3c\3c\3d\3d\3d\3d\7d\u03ba\nd\fd\16d\u03bd\13d\3d\3d"+
"\3e\3e\3e\3e\7e\u03c5\ne\fe\16e\u03c8\13e\3e\3e\3e\3e\3e\4\u02e4\u03c6"+
"\2f\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35"+
"\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36"+
";\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67"+
"m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008d"+
"H\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1"+
"R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5"+
"\\\u00b7\2\u00b9\2\u00bb\2\u00bd]\u00bf\2\u00c1\2\u00c3^\u00c5_\u00c7"+
"`\u00c9a\3\2\r\3\2$$\3\2))\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C"+
"\\aac|\6\2\62;C\\aac|\4\2--//\6\2\13\f\17\17\"\"\u00a2\u00a2\4\2\f\f\17"+
"\17\2\u043b\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2"+
"\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27"+
"\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2"+
"\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2"+
"\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2"+
"\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2"+
"\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S"+
"\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2"+
"\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2"+
"\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y"+
"\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3"+
"\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2"+
"\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095"+
"\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2"+
"\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7"+
"\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2"+
"\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00bd\3\2\2\2\2\u00c3"+
"\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\3\u00cb\3\2\2"+
"\2\5\u00d2\3\2\2\2\7\u00d4\3\2\2\2\t\u00d6\3\2\2\2\13\u00d8\3\2\2\2\r"+
"\u00da\3\2\2\2\17\u00dc\3\2\2\2\21\u00de\3\2\2\2\23\u00e0\3\2\2\2\25\u00e6"+
"\3\2\2\2\27\u00ed\3\2\2\2\31\u00f3\3\2\2\2\33\u00fc\3\2\2\2\35\u0103\3"+
"\2\2\2\37\u010c\3\2\2\2!\u0116\3\2\2\2#\u011e\3\2\2\2%\u0121\3\2\2\2\'"+
"\u0126\3\2\2\2)\u012c\3\2\2\2+\u012f\3\2\2\2-\u0133\3\2\2\2/\u013a\3\2"+
"\2\2\61\u0140\3\2\2\2\63\u0149\3\2\2\2\65\u014d\3\2\2\2\67\u014f\3\2\2"+
"\29\u0152\3\2\2\2;\u0159\3\2\2\2=\u0162\3\2\2\2?\u0164\3\2\2\2A\u0166"+
"\3\2\2\2C\u0168\3\2\2\2E\u016f\3\2\2\2G\u0172\3\2\2\2I\u0175\3\2\2\2K"+
"\u0177\3\2\2\2M\u0179\3\2\2\2O\u017b\3\2\2\2Q\u017d\3\2\2\2S\u017f\3\2"+
"\2\2U\u0182\3\2\2\2W\u0185\3\2\2\2Y\u0187\3\2\2\2[\u0189\3\2\2\2]\u018b"+
"\3\2\2\2_\u018d\3\2\2\2a\u0190\3\2\2\2c\u0193\3\2\2\2e\u0196\3\2\2\2g"+
"\u0199\3\2\2\2i\u019b\3\2\2\2k\u019d\3\2\2\2m\u01a0\3\2\2\2o\u01a3\3\2"+
"\2\2q\u01a5\3\2\2\2s\u01a8\3\2\2\2u\u01ab\3\2\2\2w\u01ae\3\2\2\2y\u01b1"+
"\3\2\2\2{\u01b4\3\2\2\2}\u01b8\3\2\2\2\177\u01bc\3\2\2\2\u0081\u01bf\3"+
"\2\2\2\u0083\u01c2\3\2\2\2\u0085\u01c5\3\2\2\2\u0087\u01cd\3\2\2\2\u0089"+
"\u01d6\3\2\2\2\u008b\u01db\3\2\2\2\u008d\u01e4\3\2\2\2\u008f\u01ea\3\2"+
"\2\2\u0091\u01f1\3\2\2\2\u0093\u01f4\3\2\2\2\u0095\u01fa\3\2\2\2\u0097"+
"\u01fc\3\2\2\2\u0099\u02dc\3\2\2\2\u009b\u02de\3\2\2\2\u009d\u030f\3\2"+
"\2\2\u009f\u0311\3\2\2\2\u00a1\u031e\3\2\2\2\u00a3\u032f\3\2\2\2\u00a5"+
"\u0333\3\2\2\2\u00a7\u0338\3\2\2\2\u00a9\u033f\3\2\2\2\u00ab\u0350\3\2"+
"\2\2\u00ad\u035e\3\2\2\2\u00af\u036f\3\2\2\2\u00b1\u037e\3\2\2\2\u00b3"+
"\u0381\3\2\2\2\u00b5\u038a\3\2\2\2\u00b7\u0391\3\2\2\2\u00b9\u0393\3\2"+
"\2\2\u00bb\u0395\3\2\2\2\u00bd\u0397\3\2\2\2\u00bf\u039e\3\2\2\2\u00c1"+
"\u03a0\3\2\2\2\u00c3\u03a2\3\2\2\2\u00c5\u03af\3\2\2\2\u00c7\u03b5\3\2"+
"\2\2\u00c9\u03c0\3\2\2\2\u00cb\u00cc\7k\2\2\u00cc\u00cd\7o\2\2\u00cd\u00ce"+
"\7r\2\2\u00ce\u00cf\7q\2\2\u00cf\u00d0\7t\2\2\u00d0\u00d1\7v\2\2\u00d1"+
"\4\3\2\2\2\u00d2\u00d3\7=\2\2\u00d3\6\3\2\2\2\u00d4\u00d5\7.\2\2\u00d5"+
"\b\3\2\2\2\u00d6\u00d7\7?\2\2\u00d7\n\3\2\2\2\u00d8\u00d9\7*\2\2\u00d9"+
"\f\3\2\2\2\u00da\u00db\7+\2\2\u00db\16\3\2\2\2\u00dc\u00dd\7}\2\2\u00dd"+
"\20\3\2\2\2\u00de\u00df\7\177\2\2\u00df\22\3\2\2\2\u00e0\u00e1\7e\2\2"+
"\u00e1\u00e2\7q\2\2\u00e2\u00e3\7p\2\2\u00e3\u00e4\7u\2\2\u00e4\u00e5"+
"\7v\2\2\u00e5\24\3\2\2\2\u00e6\u00e7\7g\2\2\u00e7\u00e8\7z\2\2\u00e8\u00e9"+
"\7v\2\2\u00e9\u00ea\7g\2\2\u00ea\u00eb\7t\2\2\u00eb\u00ec\7p\2\2\u00ec"+
"\26\3\2\2\2\u00ed\u00ee\7c\2\2\u00ee\u00ef\7n\2\2\u00ef\u00f0\7k\2\2\u00f0"+
"\u00f1\7i\2\2\u00f1\u00f2\7p\2\2\u00f2\30\3\2\2\2\u00f3\u00f4\7t\2\2\u00f4"+
"\u00f5\7g\2\2\u00f5\u00f6\7i\2\2\u00f6\u00f7\7k\2\2\u00f7\u00f8\7u\2\2"+
"\u00f8\u00f9\7v\2\2\u00f9\u00fa\7g\2\2\u00fa\u00fb\7t\2\2\u00fb\32\3\2"+
"\2\2\u00fc\u00fd\7k\2\2\u00fd\u00fe\7p\2\2\u00fe\u00ff\7n\2\2\u00ff\u0100"+
"\7k\2\2\u0100\u0101\7p\2\2\u0101\u0102\7g\2\2\u0102\34\3\2\2\2\u0103\u0104"+
"\7x\2\2\u0104\u0105\7q\2\2\u0105\u0106\7n\2\2\u0106\u0107\7c\2\2\u0107"+
"\u0108\7v\2\2\u0108\u0109\7k\2\2\u0109\u010a\7n\2\2\u010a\u010b\7g\2\2"+
"\u010b\36\3\2\2\2\u010c\u010d\7k\2\2\u010d\u010e\7p\2\2\u010e\u010f\7"+
"v\2\2\u010f\u0110\7g\2\2\u0110\u0111\7t\2\2\u0111\u0112\7t\2\2\u0112\u0113"+
"\7w\2\2\u0113\u0114\7r\2\2\u0114\u0115\7v\2\2\u0115 \3\2\2\2\u0116\u0117"+
"\7t\2\2\u0117\u0118\7g\2\2\u0118\u0119\7u\2\2\u0119\u011a\7g\2\2\u011a"+
"\u011b\7t\2\2\u011b\u011c\7x\2\2\u011c\u011d\7g\2\2\u011d\"\3\2\2\2\u011e"+
"\u011f\7k\2\2\u011f\u0120\7h\2\2\u0120$\3\2\2\2\u0121\u0122\7g\2\2\u0122"+
"\u0123\7n\2\2\u0123\u0124\7u\2\2\u0124\u0125\7g\2\2\u0125&\3\2\2\2\u0126"+
"\u0127\7y\2\2\u0127\u0128\7j\2\2\u0128\u0129\7k\2\2\u0129\u012a\7n\2\2"+
"\u012a\u012b\7g\2\2\u012b(\3\2\2\2\u012c\u012d\7f\2\2\u012d\u012e\7q\2"+
"\2\u012e*\3\2\2\2\u012f\u0130\7h\2\2\u0130\u0131\7q\2\2\u0131\u0132\7"+
"t\2\2\u0132,\3\2\2\2\u0133\u0134\7t\2\2\u0134\u0135\7g\2\2\u0135\u0136"+
"\7v\2\2\u0136\u0137\7w\2\2\u0137\u0138\7t\2\2\u0138\u0139\7p\2\2\u0139"+
".\3\2\2\2\u013a\u013b\7d\2\2\u013b\u013c\7t\2\2\u013c\u013d\7g\2\2\u013d"+
"\u013e\7c\2\2\u013e\u013f\7m\2\2\u013f\60\3\2\2\2\u0140\u0141\7e\2\2\u0141"+
"\u0142\7q\2\2\u0142\u0143\7p\2\2\u0143\u0144\7v\2\2\u0144\u0145\7k\2\2"+
"\u0145\u0146\7p\2\2\u0146\u0147\7w\2\2\u0147\u0148\7g\2\2\u0148\62\3\2"+
"\2\2\u0149\u014a\7c\2\2\u014a\u014b\7u\2\2\u014b\u014c\7o\2\2\u014c\64"+
"\3\2\2\2\u014d\u014e\7<\2\2\u014e\66\3\2\2\2\u014f\u0150\7\60\2\2\u0150"+
"\u0151\7\60\2\2\u01518\3\2\2\2\u0152\u0153\7u\2\2\u0153\u0154\7k\2\2\u0154"+
"\u0155\7i\2\2\u0155\u0156\7p\2\2\u0156\u0157\7g\2\2\u0157\u0158\7f\2\2"+
"\u0158:\3\2\2\2\u0159\u015a\7w\2\2\u015a\u015b\7p\2\2\u015b\u015c\7u\2"+
"\2\u015c\u015d\7k\2\2\u015d\u015e\7i\2\2\u015e\u015f\7p\2\2\u015f\u0160"+
"\7g\2\2\u0160\u0161\7f\2\2\u0161<\3\2\2\2\u0162\u0163\7,\2\2\u0163>\3"+
"\2\2\2\u0164\u0165\7]\2\2\u0165@\3\2\2\2\u0166\u0167\7_\2\2\u0167B\3\2"+
"\2\2\u0168\u0169\7u\2\2\u0169\u016a\7k\2\2\u016a\u016b\7|\2\2\u016b\u016c"+
"\7g\2\2\u016c\u016d\7q\2\2\u016d\u016e\7h\2\2\u016eD\3\2\2\2\u016f\u0170"+
"\7/\2\2\u0170\u0171\7/\2\2\u0171F\3\2\2\2\u0172\u0173\7-\2\2\u0173\u0174"+
"\7-\2\2\u0174H\3\2\2\2\u0175\u0176\7-\2\2\u0176J\3\2\2\2\u0177\u0178\7"+
"/\2\2\u0178L\3\2\2\2\u0179\u017a\7#\2\2\u017aN\3\2\2\2\u017b\u017c\7("+
"\2\2\u017cP\3\2\2\2\u017d\u017e\7\u0080\2\2\u017eR\3\2\2\2\u017f\u0180"+
"\7@\2\2\u0180\u0181\7@\2\2\u0181T\3\2\2\2\u0182\u0183\7>\2\2\u0183\u0184"+
"\7>\2\2\u0184V\3\2\2\2\u0185\u0186\7\61\2\2\u0186X\3\2\2\2\u0187\u0188"+
"\7\'\2\2\u0188Z\3\2\2\2\u0189\u018a\7>\2\2\u018a\\\3\2\2\2\u018b\u018c"+
"\7@\2\2\u018c^\3\2\2\2\u018d\u018e\7?\2\2\u018e\u018f\7?\2\2\u018f`\3"+
"\2\2\2\u0190\u0191\7#\2\2\u0191\u0192\7?\2\2\u0192b\3\2\2\2\u0193\u0194"+
"\7>\2\2\u0194\u0195\7?\2\2\u0195d\3\2\2\2\u0196\u0197\7@\2\2\u0197\u0198"+
"\7?\2\2\u0198f\3\2\2\2\u0199\u019a\7`\2\2\u019ah\3\2\2\2\u019b\u019c\7"+
"~\2\2\u019cj\3\2\2\2\u019d\u019e\7(\2\2\u019e\u019f\7(\2\2\u019fl\3\2"+
"\2\2\u01a0\u01a1\7~\2\2\u01a1\u01a2\7~\2\2\u01a2n\3\2\2\2\u01a3\u01a4"+
"\7A\2\2\u01a4p\3\2\2\2\u01a5\u01a6\7-\2\2\u01a6\u01a7\7?\2\2\u01a7r\3"+
"\2\2\2\u01a8\u01a9\7/\2\2\u01a9\u01aa\7?\2\2\u01aat\3\2\2\2\u01ab\u01ac"+
"\7,\2\2\u01ac\u01ad\7?\2\2\u01adv\3\2\2\2\u01ae\u01af\7\61\2\2\u01af\u01b0"+
"\7?\2\2\u01b0x\3\2\2\2\u01b1\u01b2\7\'\2\2\u01b2\u01b3\7?\2\2\u01b3z\3"+
"\2\2\2\u01b4\u01b5\7>\2\2\u01b5\u01b6\7>\2\2\u01b6\u01b7\7?\2\2\u01b7"+
"|\3\2\2\2\u01b8\u01b9\7@\2\2\u01b9\u01ba\7@\2\2\u01ba\u01bb\7?\2\2\u01bb"+
"~\3\2\2\2\u01bc\u01bd\7(\2\2\u01bd\u01be\7?\2\2\u01be\u0080\3\2\2\2\u01bf"+
"\u01c0\7~\2\2\u01c0\u01c1\7?\2\2\u01c1\u0082\3\2\2\2\u01c2\u01c3\7`\2"+
"\2\u01c3\u01c4\7?\2\2\u01c4\u0084\3\2\2\2\u01c5\u01c6\7m\2\2\u01c6\u01c7"+
"\7k\2\2\u01c7\u01c8\7e\2\2\u01c8\u01c9\7m\2\2\u01c9\u01ca\7c\2\2\u01ca"+
"\u01cb\7u\2\2\u01cb\u01cc\7o\2\2\u01cc\u0086\3\2\2\2\u01cd\u01ce\7t\2"+
"\2\u01ce\u01cf\7g\2\2\u01cf\u01d0\7u\2\2\u01d0\u01d1\7q\2\2\u01d1\u01d2"+
"\7w\2\2\u01d2\u01d3\7t\2\2\u01d3\u01d4\7e\2\2\u01d4\u01d5\7g\2\2\u01d5"+
"\u0088\3\2\2\2\u01d6\u01d7\7w\2\2\u01d7\u01d8\7u\2\2\u01d8\u01d9\7g\2"+
"\2\u01d9\u01da\7u\2\2\u01da\u008a\3\2\2\2\u01db\u01dc\7e\2\2\u01dc\u01dd"+
"\7n\2\2\u01dd\u01de\7q\2\2\u01de\u01df\7d\2\2\u01df\u01e0\7d\2\2\u01e0"+
"\u01e1\7g\2\2\u01e1\u01e2\7t\2\2\u01e2\u01e3\7u\2\2\u01e3\u008c\3\2\2"+
"\2\u01e4\u01e5\7d\2\2\u01e5\u01e6\7{\2\2\u01e6\u01e7\7v\2\2\u01e7\u01e8"+
"\7g\2\2\u01e8\u01e9\7u\2\2\u01e9\u008e\3\2\2\2\u01ea\u01eb\7e\2\2\u01eb"+
"\u01ec\7{\2\2\u01ec\u01ed\7e\2\2\u01ed\u01ee\7n\2\2\u01ee\u01ef\7g\2\2"+
"\u01ef\u01f0\7u\2\2\u01f0\u0090\3\2\2\2\u01f1\u01f2\7r\2\2\u01f2\u01f3"+
"\7e\2\2\u01f3\u0092\3\2\2\2\u01f4\u01f5\7\60\2\2\u01f5\u01f6\7d\2\2\u01f6"+
"\u01f7\7{\2\2\u01f7\u01f8\7v\2\2\u01f8\u01f9\7g\2\2\u01f9\u0094\3\2\2"+
"\2\u01fa\u01fb\7%\2\2\u01fb\u0096\3\2\2\2\u01fc\u01fd\7\60\2\2\u01fd\u0098"+
"\3\2\2\2\u01fe\u01ff\7d\2\2\u01ff\u0200\7t\2\2\u0200\u02dd\7m\2\2\u0201"+
"\u0202\7q\2\2\u0202\u0203\7t\2\2\u0203\u02dd\7c\2\2\u0204\u0205\7m\2\2"+
"\u0205\u0206\7k\2\2\u0206\u02dd\7n\2\2\u0207\u0208\7u\2\2\u0208\u0209"+
"\7n\2\2\u0209\u02dd\7q\2\2\u020a\u020b\7p\2\2\u020b\u020c\7q\2\2\u020c"+
"\u02dd\7r\2\2\u020d\u020e\7c\2\2\u020e\u020f\7u\2\2\u020f\u02dd\7n\2\2"+
"\u0210\u0211\7r\2\2\u0211\u0212\7j\2\2\u0212\u02dd\7r\2\2\u0213\u0214"+
"\7c\2\2\u0214\u0215\7p\2\2\u0215\u02dd\7e\2\2\u0216\u0217\7d\2\2\u0217"+
"\u0218\7r\2\2\u0218\u02dd\7n\2\2\u0219\u021a\7e\2\2\u021a\u021b\7n\2\2"+
"\u021b\u02dd\7e\2\2\u021c\u021d\7l\2\2\u021d\u021e\7u\2\2\u021e\u02dd"+
"\7t\2\2\u021f\u0220\7c\2\2\u0220\u0221\7p\2\2\u0221\u02dd\7f\2\2\u0222"+
"\u0223\7t\2\2\u0223\u0224\7n\2\2\u0224\u02dd\7c\2\2\u0225\u0226\7d\2\2"+
"\u0226\u0227\7k\2\2\u0227\u02dd\7v\2\2\u0228\u0229\7t\2\2\u0229\u022a"+
"\7q\2\2\u022a\u02dd\7n\2\2\u022b\u022c\7r\2\2\u022c\u022d\7n\2\2\u022d"+
"\u02dd\7c\2\2\u022e\u022f\7r\2\2\u022f\u0230\7n\2\2\u0230\u02dd\7r\2\2"+
"\u0231\u0232\7d\2\2\u0232\u0233\7o\2\2\u0233\u02dd\7k\2\2\u0234\u0235"+
"\7u\2\2\u0235\u0236\7g\2\2\u0236\u02dd\7e\2\2\u0237\u0238\7t\2\2\u0238"+
"\u0239\7v\2\2\u0239\u02dd\7k\2\2\u023a\u023b\7g\2\2\u023b\u023c\7q\2\2"+
"\u023c\u02dd\7t\2\2\u023d\u023e\7u\2\2\u023e\u023f\7t\2\2\u023f\u02dd"+
"\7g\2\2\u0240\u0241\7n\2\2\u0241\u0242\7u\2\2\u0242\u02dd\7t\2\2\u0243"+
"\u0244\7r\2\2\u0244\u0245\7j\2\2\u0245\u02dd\7c\2\2\u0246\u0247\7c\2\2"+
"\u0247\u0248\7n\2\2\u0248\u02dd\7t\2\2\u0249\u024a\7l\2\2\u024a\u024b"+
"\7o\2\2\u024b\u02dd\7r\2\2\u024c\u024d\7d\2\2\u024d\u024e\7x\2\2\u024e"+
"\u02dd\7e\2\2\u024f\u0250\7e\2\2\u0250\u0251\7n\2\2\u0251\u02dd\7k\2\2"+
"\u0252\u0253\7t\2\2\u0253\u0254\7v\2\2\u0254\u02dd\7u\2\2\u0255\u0256"+
"\7c\2\2\u0256\u0257\7f\2\2\u0257\u02dd\7e\2\2\u0258\u0259\7t\2\2\u0259"+
"\u025a\7t\2\2\u025a\u02dd\7c\2\2\u025b\u025c\7d\2\2\u025c\u025d\7x\2\2"+
"\u025d\u02dd\7u\2\2\u025e\u025f\7u\2\2\u025f\u0260\7g\2\2\u0260\u02dd"+
"\7k\2\2\u0261\u0262\7u\2\2\u0262\u0263\7c\2\2\u0263\u02dd\7z\2\2\u0264"+
"\u0265\7u\2\2\u0265\u0266\7v\2\2\u0266\u02dd\7{\2\2\u0267\u0268\7u\2\2"+
"\u0268\u0269\7v\2\2\u0269\u02dd\7c\2\2\u026a\u026b\7u\2\2\u026b\u026c"+
"\7v\2\2\u026c\u02dd\7z\2\2\u026d\u026e\7f\2\2\u026e\u026f\7g\2\2\u026f"+
"\u02dd\7{\2\2\u0270\u0271\7v\2\2\u0271\u0272\7z\2\2\u0272\u02dd\7c\2\2"+
"\u0273\u0274\7z\2\2\u0274\u0275\7c\2\2\u0275\u02dd\7c\2\2\u0276\u0277"+
"\7d\2\2\u0277\u0278\7e\2\2\u0278\u02dd\7e\2\2\u0279\u027a\7c\2\2\u027a"+
"\u027b\7j\2\2\u027b\u02dd\7z\2\2\u027c\u027d\7v\2\2\u027d\u027e\7{\2\2"+
"\u027e\u02dd\7c\2\2\u027f\u0280\7v\2\2\u0280\u0281\7z\2\2\u0281\u02dd"+
"\7u\2\2\u0282\u0283\7v\2\2\u0283\u0284\7c\2\2\u0284\u02dd\7u\2\2\u0285"+
"\u0286\7u\2\2\u0286\u0287\7j\2\2\u0287\u02dd\7{\2\2\u0288\u0289\7u\2\2"+
"\u0289\u028a\7j\2\2\u028a\u02dd\7z\2\2\u028b\u028c\7n\2\2\u028c\u028d"+
"\7f\2\2\u028d\u02dd\7{\2\2\u028e\u028f\7n\2\2\u028f\u0290\7f\2\2\u0290"+
"\u02dd\7c\2\2\u0291\u0292\7n\2\2\u0292\u0293\7f\2\2\u0293\u02dd\7z\2\2"+
"\u0294\u0295\7n\2\2\u0295\u0296\7c\2\2\u0296\u02dd\7z\2\2\u0297\u0298"+
"\7v\2\2\u0298\u0299\7c\2\2\u0299\u02dd\7{\2\2\u029a\u029b\7v\2\2\u029b"+
"\u029c\7c\2\2\u029c\u02dd\7z\2\2\u029d\u029e\7d\2\2\u029e\u029f\7e\2\2"+
"\u029f\u02dd\7u\2\2\u02a0\u02a1\7e\2\2\u02a1\u02a2\7n\2\2\u02a2\u02dd"+
"\7x\2\2\u02a3\u02a4\7v\2\2\u02a4\u02a5\7u\2\2\u02a5\u02dd\7z\2\2\u02a6"+
"\u02a7\7n\2\2\u02a7\u02a8\7c\2\2\u02a8\u02dd\7u\2\2\u02a9\u02aa\7e\2\2"+
"\u02aa\u02ab\7r\2\2\u02ab\u02dd\7{\2\2\u02ac\u02ad\7e\2\2\u02ad\u02ae"+
"\7o\2\2\u02ae\u02dd\7r\2\2\u02af\u02b0\7e\2\2\u02b0\u02b1\7r\2\2\u02b1"+
"\u02dd\7z\2\2\u02b2\u02b3\7f\2\2\u02b3\u02b4\7e\2\2\u02b4\u02dd\7r\2\2"+
"\u02b5\u02b6\7f\2\2\u02b6\u02b7\7g\2\2\u02b7\u02dd\7e\2\2\u02b8\u02b9"+
"\7k\2\2\u02b9\u02ba\7p\2\2\u02ba\u02dd\7e\2\2\u02bb\u02bc\7c\2\2\u02bc"+
"\u02bd\7z\2\2\u02bd\u02dd\7u\2\2\u02be\u02bf\7d\2\2\u02bf\u02c0\7p\2\2"+
"\u02c0\u02dd\7g\2\2\u02c1\u02c2\7e\2\2\u02c2\u02c3\7n\2\2\u02c3\u02dd"+
"\7f\2\2\u02c4\u02c5\7u\2\2\u02c5\u02c6\7d\2\2\u02c6\u02dd\7e\2\2\u02c7"+
"\u02c8\7k\2\2\u02c8\u02c9\7u\2\2\u02c9\u02dd\7e\2\2\u02ca\u02cb\7k\2\2"+
"\u02cb\u02cc\7p\2\2\u02cc\u02dd\7z\2\2\u02cd\u02ce\7d\2\2\u02ce\u02cf"+
"\7g\2\2\u02cf\u02dd\7s\2\2\u02d0\u02d1\7u\2\2\u02d1\u02d2\7g\2\2\u02d2"+
"\u02dd\7f\2\2\u02d3\u02d4\7f\2\2\u02d4\u02d5\7g\2\2\u02d5\u02dd\7z\2\2"+
"\u02d6\u02d7\7k\2\2\u02d7\u02d8\7p\2\2\u02d8\u02dd\7{\2\2\u02d9\u02da"+
"\7t\2\2\u02da\u02db\7q\2\2\u02db\u02dd\7t\2\2\u02dc\u01fe\3\2\2\2\u02dc"+
"\u0201\3\2\2\2\u02dc\u0204\3\2\2\2\u02dc\u0207\3\2\2\2\u02dc\u020a\3\2"+
"\2\2\u02dc\u020d\3\2\2\2\u02dc\u0210\3\2\2\2\u02dc\u0213\3\2\2\2\u02dc"+
"\u0216\3\2\2\2\u02dc\u0219\3\2\2\2\u02dc\u021c\3\2\2\2\u02dc\u021f\3\2"+
"\2\2\u02dc\u0222\3\2\2\2\u02dc\u0225\3\2\2\2\u02dc\u0228\3\2\2\2\u02dc"+
"\u022b\3\2\2\2\u02dc\u022e\3\2\2\2\u02dc\u0231\3\2\2\2\u02dc\u0234\3\2"+
"\2\2\u02dc\u0237\3\2\2\2\u02dc\u023a\3\2\2\2\u02dc\u023d\3\2\2\2\u02dc"+
"\u0240\3\2\2\2\u02dc\u0243\3\2\2\2\u02dc\u0246\3\2\2\2\u02dc\u0249\3\2"+
"\2\2\u02dc\u024c\3\2\2\2\u02dc\u024f\3\2\2\2\u02dc\u0252\3\2\2\2\u02dc"+
"\u0255\3\2\2\2\u02dc\u0258\3\2\2\2\u02dc\u025b\3\2\2\2\u02dc\u025e\3\2"+
"\2\2\u02dc\u0261\3\2\2\2\u02dc\u0264\3\2\2\2\u02dc\u0267\3\2\2\2\u02dc"+
"\u026a\3\2\2\2\u02dc\u026d\3\2\2\2\u02dc\u0270\3\2\2\2\u02dc\u0273\3\2"+
"\2\2\u02dc\u0276\3\2\2\2\u02dc\u0279\3\2\2\2\u02dc\u027c\3\2\2\2\u02dc"+
"\u027f\3\2\2\2\u02dc\u0282\3\2\2\2\u02dc\u0285\3\2\2\2\u02dc\u0288\3\2"+
"\2\2\u02dc\u028b\3\2\2\2\u02dc\u028e\3\2\2\2\u02dc\u0291\3\2\2\2\u02dc"+
"\u0294\3\2\2\2\u02dc\u0297\3\2\2\2\u02dc\u029a\3\2\2\2\u02dc\u029d\3\2"+
"\2\2\u02dc\u02a0\3\2\2\2\u02dc\u02a3\3\2\2\2\u02dc\u02a6\3\2\2\2\u02dc"+
"\u02a9\3\2\2\2\u02dc\u02ac\3\2\2\2\u02dc\u02af\3\2\2\2\u02dc\u02b2\3\2"+
"\2\2\u02dc\u02b5\3\2\2\2\u02dc\u02b8\3\2\2\2\u02dc\u02bb\3\2\2\2\u02dc"+
"\u02be\3\2\2\2\u02dc\u02c1\3\2\2\2\u02dc\u02c4\3\2\2\2\u02dc\u02c7\3\2"+
"\2\2\u02dc\u02ca\3\2\2\2\u02dc\u02cd\3\2\2\2\u02dc\u02d0\3\2\2\2\u02dc"+
"\u02d3\3\2\2\2\u02dc\u02d6\3\2\2\2\u02dc\u02d9\3\2\2\2\u02dd\u009a\3\2"+
"\2\2\u02de\u02df\7}\2\2\u02df\u02e0\7}\2\2\u02e0\u02e4\3\2\2\2\u02e1\u02e3"+
"\13\2\2\2\u02e2\u02e1\3\2\2\2\u02e3\u02e6\3\2\2\2\u02e4\u02e5\3\2\2\2"+
"\u02e4\u02e2\3\2\2\2\u02e5\u02e7\3\2\2\2\u02e6\u02e4\3\2\2\2\u02e7\u02e8"+
"\7\177\2\2\u02e8\u02e9\7\177\2\2\u02e9\u009c\3\2\2\2\u02ea\u02eb\7d\2"+
"\2\u02eb\u02ec\7{\2\2\u02ec\u02ed\7v\2\2\u02ed\u0310\7g\2\2\u02ee\u02ef"+
"\7y\2\2\u02ef\u02f0\7q\2\2\u02f0\u02f1\7t\2\2\u02f1\u0310\7f\2\2\u02f2"+
"\u02f3\7f\2\2\u02f3\u02f4\7y\2\2\u02f4\u02f5\7q\2\2\u02f5\u02f6\7t\2\2"+
"\u02f6\u0310\7f\2\2\u02f7\u02f8\7d\2\2\u02f8\u02f9\7q\2\2\u02f9\u02fa"+
"\7q\2\2\u02fa\u0310\7n\2\2\u02fb\u02fc\7e\2\2\u02fc\u02fd\7j\2\2\u02fd"+
"\u02fe\7c\2\2\u02fe\u0310\7t\2\2\u02ff\u0300\7u\2\2\u0300\u0301\7j\2\2"+
"\u0301\u0302\7q\2\2\u0302\u0303\7t\2\2\u0303\u0310\7v\2\2\u0304\u0305"+
"\7k\2\2\u0305\u0306\7p\2\2\u0306\u0310\7v\2\2\u0307\u0308\7n\2\2\u0308"+
"\u0309\7q\2\2\u0309\u030a\7p\2\2\u030a\u0310\7i\2\2\u030b\u030c\7x\2\2"+
"\u030c\u030d\7q\2\2\u030d\u030e\7k\2\2\u030e\u0310\7f\2\2\u030f\u02ea"+
"\3\2\2\2\u030f\u02ee\3\2\2\2\u030f\u02f2\3\2\2\2\u030f\u02f7\3\2\2\2\u030f"+
"\u02fb\3\2\2\2\u030f\u02ff\3\2\2\2\u030f\u0304\3\2\2\2\u030f\u0307\3\2"+
"\2\2\u030f\u030b\3\2\2\2\u0310\u009e\3\2\2\2\u0311\u0317\7$\2\2\u0312"+
"\u0313\7^\2\2\u0313\u0316\7$\2\2\u0314\u0316\n\2\2\2\u0315\u0312\3\2\2"+
"\2\u0315\u0314\3\2\2\2\u0316\u0319\3\2\2\2\u0317\u0315\3\2\2\2\u0317\u0318"+
"\3\2\2\2\u0318\u031a\3\2\2\2\u0319\u0317\3\2\2\2\u031a\u031c\7$\2\2\u031b"+
"\u031d\7|\2\2\u031c\u031b\3\2\2\2\u031c\u031d\3\2\2\2\u031d\u00a0\3\2"+
"\2\2\u031e\u0322\7)\2\2\u031f\u0320\7^\2\2\u0320\u0323\7)\2\2\u0321\u0323"+
"\n\3\2\2\u0322\u031f\3\2\2\2\u0322\u0321\3\2\2\2\u0323\u0324\3\2\2\2\u0324"+
"\u0325\7)\2\2\u0325\u00a2\3\2\2\2\u0326\u0327\7v\2\2\u0327\u0328\7t\2"+
"\2\u0328\u0329\7w\2\2\u0329\u0330\7g\2\2\u032a\u032b\7h\2\2\u032b\u032c"+
"\7c\2\2\u032c\u032d\7n\2\2\u032d\u032e\7u\2\2\u032e\u0330\7g\2\2\u032f"+
"\u0326\3\2\2\2\u032f\u032a\3\2\2\2\u0330\u00a4\3\2\2\2\u0331\u0334\5\u00a7"+
"T\2\u0332\u0334\5\u00afX\2\u0333\u0331\3\2\2\2\u0333\u0332\3\2\2\2\u0334"+
"\u00a6\3\2\2\2\u0335\u0339\5\u00a9U\2\u0336\u0339\5\u00abV\2\u0337\u0339"+
"\5\u00adW\2\u0338\u0335\3\2\2\2\u0338\u0336\3\2\2\2\u0338\u0337\3\2\2"+
"\2\u0339\u00a8\3\2\2\2\u033a\u0340\7\'\2\2\u033b\u033c\7\62\2\2\u033c"+
"\u0340\7d\2\2\u033d\u033e\7\62\2\2\u033e\u0340\7D\2\2\u033f\u033a\3\2"+
"\2\2\u033f\u033b\3\2\2\2\u033f\u033d\3\2\2\2\u0340\u0344\3\2\2\2\u0341"+
"\u0343\5\u00b7\\\2\u0342\u0341\3\2\2\2\u0343\u0346\3\2\2\2\u0344\u0342"+
"\3\2\2\2\u0344\u0345\3\2\2\2\u0345\u0347\3\2\2\2\u0346\u0344\3\2\2\2\u0347"+
"\u0349\7\60\2\2\u0348\u034a\5\u00b7\\\2\u0349\u0348\3\2\2\2\u034a\u034b"+
"\3\2\2\2\u034b\u0349\3\2\2\2\u034b\u034c\3\2\2\2\u034c\u00aa\3\2\2\2\u034d"+
"\u034f\5\u00b9]\2\u034e\u034d\3\2\2\2\u034f\u0352\3\2\2\2\u0350\u034e"+
"\3\2\2\2\u0350\u0351\3\2\2\2\u0351\u0353\3\2\2\2\u0352\u0350\3\2\2\2\u0353"+
"\u0355\7\60\2\2\u0354\u0356\5\u00b9]\2\u0355\u0354\3\2\2\2\u0356\u0357"+
"\3\2\2\2\u0357\u0355\3\2\2\2\u0357\u0358\3\2\2\2\u0358\u00ac\3\2\2\2\u0359"+
"\u035f\7&\2\2\u035a\u035b\7\62\2\2\u035b\u035f\7z\2\2\u035c\u035d\7\62"+
"\2\2\u035d\u035f\7Z\2\2\u035e\u0359\3\2\2\2\u035e\u035a\3\2\2\2\u035e"+
"\u035c\3\2\2\2\u035f\u0363\3\2\2\2\u0360\u0362\5\u00bb^\2\u0361\u0360"+
"\3\2\2\2\u0362\u0365\3\2\2\2\u0363\u0361\3\2\2\2\u0363\u0364\3\2\2\2\u0364"+
"\u0366\3\2\2\2\u0365\u0363\3\2\2\2\u0366\u0368\7\60\2\2\u0367\u0369\5"+
"\u00bb^\2\u0368\u0367\3\2\2\2\u0369\u036a\3\2\2\2\u036a\u0368\3\2\2\2"+
"\u036a\u036b\3\2\2\2\u036b\u00ae\3\2\2\2\u036c\u0370\5\u00b3Z\2\u036d"+
"\u0370\5\u00b5[\2\u036e\u0370\5\u00b1Y\2\u036f\u036c\3\2\2\2\u036f\u036d"+
"\3\2\2\2\u036f\u036e\3\2\2\2\u0370\u00b0\3\2\2\2\u0371\u0372\7\62\2\2"+
"\u0372\u0374\t\4\2\2\u0373\u0375\5\u00b7\\\2\u0374\u0373\3\2\2\2\u0375"+
"\u0376\3\2\2\2\u0376\u0374\3\2\2\2\u0376\u0377\3\2\2\2\u0377\u037f\3\2"+
"\2\2\u0378\u037a\7\'\2\2\u0379\u037b\5\u00b7\\\2\u037a\u0379\3\2\2\2\u037b"+
"\u037c\3\2\2\2\u037c\u037a\3\2\2\2\u037c\u037d\3\2\2\2\u037d\u037f\3\2"+
"\2\2\u037e\u0371\3\2\2\2\u037e\u0378\3\2\2\2\u037f\u00b2\3\2\2\2\u0380"+
"\u0382\5\u00b9]\2\u0381\u0380\3\2\2\2\u0382\u0383\3\2\2\2\u0383\u0381"+
"\3\2\2\2\u0383\u0384\3\2\2\2\u0384\u00b4\3\2\2\2\u0385\u038b\7&\2\2\u0386"+
"\u0387\7\62\2\2\u0387\u038b\7z\2\2\u0388\u0389\7\62\2\2\u0389\u038b\7"+
"Z\2\2\u038a\u0385\3\2\2\2\u038a\u0386\3\2\2\2\u038a\u0388\3\2\2\2\u038b"+
"\u038d\3\2\2\2\u038c\u038e\5\u00bb^\2\u038d\u038c\3\2\2\2\u038e\u038f"+
"\3\2\2\2\u038f\u038d\3\2\2\2\u038f\u0390\3\2\2\2\u0390\u00b6\3\2\2\2\u0391"+
"\u0392\t\5\2\2\u0392\u00b8\3\2\2\2\u0393\u0394\t\6\2\2\u0394\u00ba\3\2"+
"\2\2\u0395\u0396\t\7\2\2\u0396\u00bc\3\2\2\2\u0397\u039b\5\u00bf`\2\u0398"+
"\u039a\5\u00c1a\2\u0399\u0398\3\2\2\2\u039a\u039d\3\2\2\2\u039b\u0399"+
"\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u00be\3\2\2\2\u039d\u039b\3\2\2\2\u039e"+
"\u039f\t\b\2\2\u039f\u00c0\3\2\2\2\u03a0\u03a1\t\t\2\2\u03a1\u00c2\3\2"+
"\2\2\u03a2\u03a6\7#\2\2\u03a3\u03a5\5\u00c1a\2\u03a4\u03a3\3\2\2\2\u03a5"+
"\u03a8\3\2\2\2\u03a6\u03a4\3\2\2\2\u03a6\u03a7\3\2\2\2\u03a7\u03aa\3\2"+
"\2\2\u03a8\u03a6\3\2\2\2\u03a9\u03ab\t\n\2\2\u03aa\u03a9\3\2\2\2\u03ab"+
"\u03ac\3\2\2\2\u03ac\u03aa\3\2\2\2\u03ac\u03ad\3\2\2\2\u03ad\u00c4\3\2"+
"\2\2\u03ae\u03b0\t\13\2\2\u03af\u03ae\3\2\2\2\u03b0\u03b1\3\2\2\2\u03b1"+
"\u03af\3\2\2\2\u03b1\u03b2\3\2\2\2\u03b2\u03b3\3\2\2\2\u03b3\u03b4\bc"+
"\2\2\u03b4\u00c6\3\2\2\2\u03b5\u03b6\7\61\2\2\u03b6\u03b7\7\61\2\2\u03b7"+
"\u03bb\3\2\2\2\u03b8\u03ba\n\f\2\2\u03b9\u03b8\3\2\2\2\u03ba\u03bd\3\2"+
"\2\2\u03bb\u03b9\3\2\2\2\u03bb\u03bc\3\2\2\2\u03bc\u03be\3\2\2\2\u03bd"+
"\u03bb\3\2\2\2\u03be\u03bf\bd\3\2\u03bf\u00c8\3\2\2\2\u03c0\u03c1\7\61"+
"\2\2\u03c1\u03c2\7,\2\2\u03c2\u03c6\3\2\2\2\u03c3\u03c5\13\2\2\2\u03c4"+
"\u03c3\3\2\2\2\u03c5\u03c8\3\2\2\2\u03c6\u03c7\3\2\2\2\u03c6\u03c4\3\2"+
"\2\2\u03c7\u03c9\3\2\2\2\u03c8\u03c6\3\2\2\2\u03c9\u03ca\7,\2\2\u03ca"+
"\u03cb\7\61\2\2\u03cb\u03cc\3\2\2\2\u03cc\u03cd\be\3\2\u03cd\u00ca\3\2"+
"\2\2\"\2\u02dc\u02e4\u030f\u0315\u0317\u031c\u0322\u032f\u0333\u0338\u033f"+
"\u0344\u034b\u0350\u0357\u035e\u0363\u036a\u036f\u0376\u037c\u037e\u0383"+
"\u038a\u038f\u039b\u03a6\u03ac\u03b1\u03bb\u03c6\4\2\3\2\2\4\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -72,26 +72,27 @@ T__70=71
T__71=72
T__72=73
T__73=74
MNEMONIC=75
KICKASM=76
SIMPLETYPE=77
STRING=78
CHAR=79
BOOLEAN=80
NUMBER=81
NUMFLOAT=82
BINFLOAT=83
DECFLOAT=84
HEXFLOAT=85
NUMINT=86
BININTEGER=87
DECINTEGER=88
HEXINTEGER=89
NAME=90
ASMREL=91
WS=92
COMMENT_LINE=93
COMMENT_BLOCK=94
T__74=75
MNEMONIC=76
KICKASM=77
SIMPLETYPE=78
STRING=79
CHAR=80
BOOLEAN=81
NUMBER=82
NUMFLOAT=83
BINFLOAT=84
DECFLOAT=85
HEXFLOAT=86
NUMINT=87
BININTEGER=88
DECINTEGER=89
HEXINTEGER=90
NAME=91
ASMREL=92
WS=93
COMMENT_LINE=94
COMMENT_BLOCK=95
'import'=1
';'=2
','=3
@ -107,62 +108,63 @@ COMMENT_BLOCK=94
'inline'=13
'volatile'=14
'interrupt'=15
'if'=16
'else'=17
'while'=18
'do'=19
'for'=20
'return'=21
'break'=22
'continue'=23
'asm'=24
':'=25
'..'=26
'signed'=27
'unsigned'=28
'*'=29
'['=30
']'=31
'sizeof'=32
'--'=33
'++'=34
'+'=35
'-'=36
'!'=37
'&'=38
'~'=39
'>>'=40
'<<'=41
'/'=42
'%'=43
'<'=44
'>'=45
'=='=46
'!='=47
'<='=48
'>='=49
'^'=50
'|'=51
'&&'=52
'||'=53
'?'=54
'+='=55
'-='=56
'*='=57
'/='=58
'%='=59
'<<='=60
'>>='=61
'&='=62
'|='=63
'^='=64
'kickasm'=65
'resource'=66
'uses'=67
'clobbers'=68
'bytes'=69
'cycles'=70
'pc'=71
'.byte'=72
'#'=73
'.'=74
'reserve'=16
'if'=17
'else'=18
'while'=19
'do'=20
'for'=21
'return'=22
'break'=23
'continue'=24
'asm'=25
':'=26
'..'=27
'signed'=28
'unsigned'=29
'*'=30
'['=31
']'=32
'sizeof'=33
'--'=34
'++'=35
'+'=36
'-'=37
'!'=38
'&'=39
'~'=40
'>>'=41
'<<'=42
'/'=43
'%'=44
'<'=45
'>'=46
'=='=47
'!='=48
'<='=49
'>='=50
'^'=51
'|'=52
'&&'=53
'||'=54
'?'=55
'+='=56
'-='=57
'*='=58
'/='=59
'%='=60
'<<='=61
'>>='=62
'&='=63
'|='=64
'^='=65
'kickasm'=66
'resource'=67
'uses'=68
'clobbers'=69
'bytes'=70
'cycles'=71
'pc'=72
'.byte'=73
'#'=74
'.'=75

View File

@ -151,6 +151,16 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#globalDirective}.
* @param ctx the parse tree
*/
void enterGlobalDirective(KickCParser.GlobalDirectiveContext ctx);
/**
* Exit a parse tree produced by {@link KickCParser#globalDirective}.
* @param ctx the parse tree
*/
void exitGlobalDirective(KickCParser.GlobalDirectiveContext ctx);
/**
* Enter a parse tree produced by the {@code directiveConst}
* labeled alternative in {@link KickCParser#directive}.
@ -235,6 +245,28 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitDirectiveInterrupt(KickCParser.DirectiveInterruptContext ctx);
/**
* Enter a parse tree produced by the {@code directiveReserveZp}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx);
/**
* Exit a parse tree produced by the {@code directiveReserveZp}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#directiveReserve}.
* @param ctx the parse tree
*/
void enterDirectiveReserve(KickCParser.DirectiveReserveContext ctx);
/**
* Exit a parse tree produced by {@link KickCParser#directiveReserve}.
* @param ctx the parse tree
*/
void exitDirectiveReserve(KickCParser.DirectiveReserveContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#stmtSeq}.
* @param ctx the parse tree

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,12 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#globalDirective}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGlobalDirective(KickCParser.GlobalDirectiveContext ctx);
/**
* Visit a parse tree produced by the {@code directiveConst}
* labeled alternative in {@link KickCParser#directive}.
@ -145,6 +151,19 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitDirectiveInterrupt(KickCParser.DirectiveInterruptContext ctx);
/**
* Visit a parse tree produced by the {@code directiveReserveZp}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#directiveReserve}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveReserve(KickCParser.DirectiveReserveContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#stmtSeq}.
* @param ctx the parse tree

View File

@ -110,6 +110,15 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
return null;
}
@Override
public Object visitGlobalDirective(KickCParser.GlobalDirectiveContext ctx) {
DirectiveReserveZp reserveDirective = (DirectiveReserveZp) this.visit(ctx.directiveReserve());
if(reserveDirective!=null) {
program.addReservedZps(reserveDirective.getReservedZp());
}
return null;
}
@Override
public Object visitDeclFunction(KickCParser.DeclFunctionContext ctx) {
this.visitDeclTypes(ctx.declTypes());
@ -573,6 +582,8 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
procedure.setDeclaredInline(true);
} else if(directive instanceof DirectiveInterrupt) {
procedure.setInterruptType(((DirectiveInterrupt) directive).interruptType);
} else if(directive instanceof DirectiveReserveZp) {
procedure.setReservedZps(((DirectiveReserveZp) directive).getReservedZp());
} else {
throw new CompileError("Unsupported function directive " + directive, source);
}
@ -597,7 +608,6 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
}
@Override
public Directive visitDirectiveConst(KickCParser.DirectiveConstContext ctx) {
return new DirectiveConst();
@ -638,6 +648,16 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
return new DirectiveVolatile();
}
@Override
public Object visitDirectiveReserve(KickCParser.DirectiveReserveContext ctx) {
List<Number> reservedZps = new ArrayList<>();
for(TerminalNode reservedNum : ctx.NUMBER()) {
Number reservedZp = NumberParser.parseLiteral(reservedNum.getText());
reservedZps.add(reservedZp);
}
return new DirectiveReserveZp(reservedZps);
}
@Override
public Void visitStmtSeq(KickCParser.StmtSeqContext ctx) {
for(int i = 0; i < ctx.getChildCount(); i++) {
@ -1542,6 +1562,20 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
}
/** Reservation of zero-page addresses */
private static class DirectiveReserveZp implements Directive {
List<Number> reservedZp;
public DirectiveReserveZp(List<Number> reservedZp) {
this.reservedZp = reservedZp;
}
public List<Number> getReservedZp() {
return reservedZp;
}
}
private static class PrePostModifierHandler extends KickCBaseVisitor<Void> {

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.values.VariableRef;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.Scope;
@ -8,9 +9,7 @@ import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;
/**
* Move register allocation from equivalence classes to RegisterAllocation.
@ -23,8 +22,19 @@ public class Pass4RegistersFinalize extends Pass2Base {
*/
private int currentZp = 2;
/** All reserved zeropage addresses not available for the compiler. */
private List<Number> reservedZp;
public Pass4RegistersFinalize(Program program) {
super(program);
this.reservedZp = new ArrayList<>();
this.reservedZp.addAll(program.getReservedZps());
for(Procedure procedure : getSymbols().getAllProcedures(true)) {
List<Number> procedureReservedZps = procedure.getReservedZps();
if(procedureReservedZps!=null) {
this.reservedZp.addAll(procedureReservedZps);
}
}
}
public void allocate(boolean reallocateZp) {
@ -150,6 +160,32 @@ public class Pass4RegistersFinalize extends Pass2Base {
}
}
/**
* Allocate bytes on zeropage.
* Avoids reserved zero page addresses.
* @param size The number of bytes to allocate
* @return The address of the first byte.
*/
private int allocateZp(int size) {
// Find a ZP sequence of size without any reserved ZP
boolean reserved;
do {
reserved = false;
int candidateZp = currentZp;
for(int i=0;i<size;i++) {
if(reservedZp.contains(new Long(candidateZp+i))) {
reserved = true;
currentZp++;
break;
}
}
} while(reserved);
// No reserved ZP
int allocated = currentZp;
currentZp += size;
return allocated;
}
/**
* Create a new register for a specific variable type.
*
@ -160,38 +196,33 @@ public class Pass4RegistersFinalize extends Pass2Base {
private Registers.Register allocateNewRegisterZp(Variable variable) {
SymbolType varType = variable.getType();
if(SymbolType.isByte(varType)) {
return new Registers.RegisterZpByte(currentZp++);
return new Registers.RegisterZpByte(allocateZp((1)));
} else if(SymbolType.isSByte(varType)) {
return new Registers.RegisterZpByte(currentZp++);
return new Registers.RegisterZpByte(allocateZp(1));
} else if(SymbolType.isWord(varType)) {
Registers.RegisterZpWord registerZpWord =
new Registers.RegisterZpWord(currentZp);
currentZp = currentZp + 2;
new Registers.RegisterZpWord(allocateZp(2));
return registerZpWord;
} else if(SymbolType.isSWord(varType)) {
Registers.RegisterZpWord registerZpWord =
new Registers.RegisterZpWord(currentZp);
currentZp = currentZp + 2;
new Registers.RegisterZpWord(allocateZp(2));
return registerZpWord;
} else if(SymbolType.isDWord(varType)) {
Registers.RegisterZpDWord registerZpDWord =
new Registers.RegisterZpDWord(currentZp);
currentZp = currentZp + 4;
new Registers.RegisterZpDWord(allocateZp(4));
return registerZpDWord;
} else if(SymbolType.isSDWord(varType)) {
Registers.RegisterZpDWord registerZpDWord =
new Registers.RegisterZpDWord(currentZp);
currentZp = currentZp + 4;
new Registers.RegisterZpDWord(allocateZp(4));
return registerZpDWord;
} else if(varType.equals(SymbolType.BOOLEAN)) {
return new Registers.RegisterZpBool(currentZp++);
return new Registers.RegisterZpBool(allocateZp(1));
} else if(varType.equals(SymbolType.VOID)) {
// No need to setRegister register for VOID value
return null;
} else if(varType instanceof SymbolTypePointer) {
Registers.RegisterZpWord registerZpWord =
new Registers.RegisterZpWord(currentZp);
currentZp = currentZp + 2;
new Registers.RegisterZpWord(allocateZp(2));
return registerZpWord;
} else {
throw new RuntimeException("Unhandled variable type " + varType);

View File

@ -37,6 +37,26 @@ public class TestPrograms {
// compileAndCompare("pointer-cast-3");
//}
@Test
public void testReserveZpGlobal() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-global");
}
@Test
public void testReserveZpProcedure3() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-procedure-3");
}
@Test
public void testReserveZpProcedure2() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-procedure-2");
}
@Test
public void testReserveZpProcedure1() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-procedure-1");
}
@Test
public void testWordPointerCompound() throws IOException, URISyntaxException {
compileAndCompare("word-pointer-compound");

View File

@ -11,26 +11,27 @@ const byte SIZE = 4;
const byte DELAY = 8;
// The coordinates of the lines to animate
word[4] x_start = { 10, 20, 30, 30 };
byte[4] y_start = { 10, 10, 10, 20 };
word[4] x_end = { 20, 10, 20, 20 };
byte[4] y_end = { 20, 20, 10, 20 };
word[SIZE] x_start = { 10, 20, 30, 30 };
byte[SIZE] y_start = { 10, 10, 10, 20 };
word[SIZE] x_end = { 20, 10, 20, 20 };
byte[SIZE] y_end = { 20, 20, 10, 20 };
// Current x position fixed point [12.4]
word[4] x_cur;
word[SIZE] x_cur;
// Current y position fixed point [12.4]
word[4] y_cur;
word[SIZE] y_cur;
// X position addition per frame s[3.4]
signed byte[4] x_add;
signed byte[SIZE] x_add;
// Y position addition per frame s[3.4]
signed byte[4] y_add;
signed byte[SIZE] y_add;
// Frame delay (counted down to 0)
byte[4] delay;
byte[SIZE] delay;
// Frame number (counted down to 0)
byte[4] frame;
byte[SIZE] frame;
void main() {
asm { sei } // Disable normal interrupt
// Disable normal interrupt
asm { sei }
// Disable kernal & basic
*PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK;
*PROCPORT = PROCPORT_RAM_IO;
@ -40,7 +41,7 @@ void main() {
bitmap_init(BITMAP);
bitmap_clear();
screen_fill(SCREEN, $10);
for( byte i=0; i!=4; i++) {
for( byte i : 0..SIZE-1) {
point_init(i);
bitmap_plot(x_start[i], y_start[i]);
}

View File

@ -0,0 +1,15 @@
// Demonstrates global directive reserving addresses on zeropage
reserve(2,3,5);
void main() {
const byte* SCREEN = $400;
for( volatile byte i : 0..2) {
SCREEN[i] = sub1(i);
}
}
reserve(4) byte sub1(byte i) {
return i+i;
}

View File

@ -0,0 +1,12 @@
// Demonstrates a procedure reserving addresses on zeropage
void main() {
const byte* SCREEN = $400;
for( volatile byte i : 0..2) {
SCREEN[i] = sub1(i);
}
}
reserve(2, 3, 4) byte sub1(byte i) {
return i+i;
}

View File

@ -0,0 +1,17 @@
// Demonstrates a procedure reserving addresses on zeropage
void main() {
const byte* SCREEN = $400;
for( volatile byte i : 0..2) {
SCREEN[i] = sub1(i);
(SCREEN+40)[i] = sub2(i);
}
}
reserve(2, 3, 4) byte sub1(byte i) {
return i+i;
}
reserve(5, 6, 7) byte sub2(byte i) {
return i+i+i;
}

View File

@ -0,0 +1,16 @@
// Demonstrates a procedure reserving addresses on zeropage
void main() {
const byte* SCREEN = $400;
for( volatile byte i : 0..2) {
SCREEN[i] = sub1(i);
}
}
reserve(2, 3, 4) byte sub1(byte i) {
return i+i;
}
reserve(5, 6, 7) byte sub2(byte i) {
return i+i+i;
}

View File

@ -23,14 +23,16 @@
.label CIA2_PORT_A_DDR = $dd02
.label BITMAP = $a000
.label SCREEN = $8800
// The number of points
.const SIZE = 4
// The delay between pixels
.const DELAY = 8
main: {
.const vicSelectGfxBank1_toDd001_return = 3^(>SCREEN)/$40
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f
.label i = 2
sei
// Disable normal interrupt
sei
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
@ -62,7 +64,7 @@ main: {
ldx y_start,y
jsr bitmap_plot
inc i
lda #4
lda #SIZE-1+1
cmp i
bne b1
b2:
@ -508,17 +510,17 @@ bitmap_init: {
y_start: .byte $a, $a, $a, $14
x_end: .word $14, $a, $14, $14
y_end: .byte $14, $14, $a, $14
// Current x position fixed point [12.4]
x_cur: .fill 2*4, 0
// Current y position fixed point [12.4]
y_cur: .fill 2*4, 0
// X position addition per frame s[3.4]
x_add: .fill 4, 0
// Y position addition per frame s[3.4]
y_add: .fill 4, 0
// Frame delay (counted down to 0)
delay: .fill 4, 0
// Tables for the plotter - initialized by calling bitmap_init();
bitmap_plot_ylo: .fill $100, 0
bitmap_plot_yhi: .fill $100, 0
bitmap_plot_bit: .fill $100, 0
// Current x position fixed point [12.4]
x_cur: .fill 2*SIZE, 0
// Current y position fixed point [12.4]
y_cur: .fill 2*SIZE, 0
// X position addition per frame s[3.4]
x_add: .fill SIZE, 0
// Y position addition per frame s[3.4]
y_add: .fill SIZE, 0
// Frame delay (counted down to 0)
delay: .fill SIZE, 0

View File

@ -43,14 +43,14 @@ main::@1: scope:[main] from main::@6 main::@8
[20] call point_init
to:main::@7
main::@7: scope:[main] from main::@1
[21] (byte) main::$12 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
[22] (word) bitmap_plot::x#0 ← *((const word[4]) x_start#0 + (byte) main::$12)
[23] (byte) bitmap_plot::y#0 ← *((const byte[4]) y_start#0 + (byte) main::i#2)
[21] (byte) main::$13 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
[22] (word) bitmap_plot::x#0 ← *((const word[SIZE#0]) x_start#0 + (byte) main::$13)
[23] (byte) bitmap_plot::y#0 ← *((const byte[SIZE#0]) y_start#0 + (byte) main::i#2)
[24] call bitmap_plot
to:main::@8
main::@8: scope:[main] from main::@7
[25] (byte) main::i#1 ← ++ (byte) main::i#2
[26] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto main::@1
[26] if((byte) main::i#1!=(const byte) SIZE#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@2 main::@3 main::@8
[27] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $ff) goto main::@2
@ -71,9 +71,9 @@ bitmap_plot::@return: scope:[bitmap_plot] from bitmap_plot
point_init: scope:[point_init] from main::@1
[35] (byte) point_init::$18 ← (byte) point_init::point_idx#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
[36] (byte) point_init::$19 ← (byte) point_init::point_idx#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
[37] (signed word) point_init::x_diff#1 ← (signed word)*((const word[4]) x_end#0 + (byte) point_init::$18) - (signed word)*((const word[4]) x_start#0 + (byte) point_init::$19)
[38] (signed word~) point_init::$3 ← ((signed word)) *((const byte[4]) y_end#0 + (byte) point_init::point_idx#0)
[39] (signed word~) point_init::$4 ← ((signed word)) *((const byte[4]) y_start#0 + (byte) point_init::point_idx#0)
[37] (signed word) point_init::x_diff#1 ← (signed word)*((const word[SIZE#0]) x_end#0 + (byte) point_init::$18) - (signed word)*((const word[SIZE#0]) x_start#0 + (byte) point_init::$19)
[38] (signed word~) point_init::$3 ← ((signed word)) *((const byte[SIZE#0]) y_end#0 + (byte) point_init::point_idx#0)
[39] (signed word~) point_init::$4 ← ((signed word)) *((const byte[SIZE#0]) y_start#0 + (byte) point_init::point_idx#0)
[40] (signed word) point_init::y_diff#0 ← (signed word~) point_init::$3 - (signed word~) point_init::$4
to:point_init::abs16s1
point_init::abs16s1: scope:[point_init] from point_init
@ -99,14 +99,14 @@ point_init::@6: scope:[point_init] from point_init::abs16s2_@return
to:point_init::@2
point_init::@2: scope:[point_init] from point_init::@6 point_init::@7
[48] (byte) point_init::$20 ← (byte) point_init::point_idx#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
[49] (word~) point_init::$9 ← *((const word[4]) x_start#0 + (byte) point_init::$20) << (byte/signed byte/word/signed word/dword/signed dword) 4
[49] (word~) point_init::$9 ← *((const word[SIZE#0]) x_start#0 + (byte) point_init::$20) << (byte/signed byte/word/signed word/dword/signed dword) 4
[50] (byte) point_init::$21 ← (byte) point_init::point_idx#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
[51] *((const word[4]) x_cur#0 + (byte) point_init::$21) ← (word~) point_init::$9
[52] (word~) point_init::$10 ← ((word)) *((const byte[4]) y_start#0 + (byte) point_init::point_idx#0)
[51] *((const word[SIZE#0]) x_cur#0 + (byte) point_init::$21) ← (word~) point_init::$9
[52] (word~) point_init::$10 ← ((word)) *((const byte[SIZE#0]) y_start#0 + (byte) point_init::point_idx#0)
[53] (word~) point_init::$11 ← (word~) point_init::$10 << (byte/signed byte/word/signed word/dword/signed dword) 4
[54] (byte) point_init::$22 ← (byte) point_init::point_idx#0 << (byte/signed byte/word/signed word/dword/signed dword) 1
[55] *((const word[4]) y_cur#0 + (byte) point_init::$22) ← (word~) point_init::$11
[56] *((const byte[4]) delay#0 + (byte) point_init::point_idx#0) ← (const byte) DELAY#0
[55] *((const word[SIZE#0]) y_cur#0 + (byte) point_init::$22) ← (word~) point_init::$11
[56] *((const byte[SIZE#0]) delay#0 + (byte) point_init::point_idx#0) ← (const byte) DELAY#0
to:point_init::@return
point_init::@return: scope:[point_init] from point_init::@2
[57] return
@ -115,7 +115,7 @@ point_init::@1: scope:[point_init] from point_init::@6
[58] if((signed word) point_init::x_diff#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto point_init::@4
to:point_init::@3
point_init::@3: scope:[point_init] from point_init::@1
[59] *((const signed byte[4]) x_add#0 + (byte) point_init::point_idx#0) ← (byte/signed byte/word/signed word/dword/signed dword) $10
[59] *((const signed byte[SIZE#0]) x_add#0 + (byte) point_init::point_idx#0) ← (byte/signed byte/word/signed word/dword/signed dword) $10
to:point_init::@5
point_init::@5: scope:[point_init] from point_init::@3 point_init::@4
[60] (signed word) divr16s::divisor#0 ← (signed word) point_init::x_diff#1
@ -127,10 +127,10 @@ point_init::@7: scope:[point_init] from point_init::@5
[64] (signed word) point_init::x_stepf#0 ← (signed word) divr16s::return#3
[65] (byte~) point_init::$15 ← > (signed word) point_init::x_stepf#0
[66] (byte~) point_init::$16 ← (byte~) point_init::$15 >> (byte/signed byte/word/signed word/dword/signed dword) 4
[67] *((const signed byte[4]) y_add#0 + (byte) point_init::point_idx#0) ← (signed byte)(byte~) point_init::$16
[67] *((const signed byte[SIZE#0]) y_add#0 + (byte) point_init::point_idx#0) ← (signed byte)(byte~) point_init::$16
to:point_init::@2
point_init::@4: scope:[point_init] from point_init::@1
[68] *((const signed byte[4]) x_add#0 + (byte) point_init::point_idx#0) ← -(byte/signed byte/word/signed word/dword/signed dword) $10
[68] *((const signed byte[SIZE#0]) x_add#0 + (byte) point_init::point_idx#0) ← -(byte/signed byte/word/signed word/dword/signed dword) $10
to:point_init::@5
point_init::abs16s2_@1: scope:[point_init] from point_init::abs16s2
[69] (signed word) point_init::abs16s2_$2#0 ← - (signed word) point_init::y_diff#0

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,8 @@
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) $d012
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/dword/signed dword) $8800
(byte) SIZE
(const byte) SIZE#0 SIZE = (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) VIC_BMM
(const byte) VIC_BMM#0 VIC_BMM = (byte/signed byte/word/signed word/dword/signed dword) $20
(byte) VIC_DEN
@ -95,8 +97,8 @@
(const byte[$100]) bitmap_plot_yhi#0 bitmap_plot_yhi = { fill( $100, 0) }
(byte[$100]) bitmap_plot_ylo
(const byte[$100]) bitmap_plot_ylo#0 bitmap_plot_ylo = { fill( $100, 0) }
(byte[4]) delay
(const byte[4]) delay#0 delay = { fill( 4, 0) }
(byte[SIZE#0]) delay
(const byte[SIZE#0]) delay#0 delay = { fill( SIZE#0, 0) }
(signed word()) divr16s((signed word) divr16s::dividend , (signed word) divr16s::divisor , (signed word) divr16s::rem)
(signed word~) divr16s::$10 $10 zp ZP_WORD:7 2.0
(signed word~) divr16s::$13 $13 zp ZP_WORD:9 1.0
@ -172,7 +174,7 @@
(word) divr16u::return#0 return zp ZP_WORD:5 61.0
(word) divr16u::return#2 return zp ZP_WORD:5 4.0
(void()) main()
(byte) main::$12 reg byte a 22.0
(byte) main::$13 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@3
@ -284,22 +286,22 @@
(byte) screen_fill::y
(byte) screen_fill::y#1 y zp ZP_BYTE:2 16.5
(byte) screen_fill::y#4 y zp ZP_BYTE:2 3.6666666666666665
(signed byte[4]) x_add
(const signed byte[4]) x_add#0 x_add = { fill( 4, 0) }
(word[4]) x_cur
(const word[4]) x_cur#0 x_cur = { fill( 4, 0) }
(word[4]) x_end
(const word[4]) x_end#0 x_end = { (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $14 }
(word[4]) x_start
(const word[4]) x_start#0 x_start = { (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $1e, (byte/signed byte/word/signed word/dword/signed dword) $1e }
(signed byte[4]) y_add
(const signed byte[4]) y_add#0 y_add = { fill( 4, 0) }
(word[4]) y_cur
(const word[4]) y_cur#0 y_cur = { fill( 4, 0) }
(byte[4]) y_end
(const byte[4]) y_end#0 y_end = { (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14 }
(byte[4]) y_start
(const byte[4]) y_start#0 y_start = { (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14 }
(signed byte[SIZE#0]) x_add
(const signed byte[SIZE#0]) x_add#0 x_add = { fill( SIZE#0, 0) }
(word[SIZE#0]) x_cur
(const word[SIZE#0]) x_cur#0 x_cur = { fill( SIZE#0, 0) }
(word[SIZE#0]) x_end
(const word[SIZE#0]) x_end#0 x_end = { (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $14 }
(word[SIZE#0]) x_start
(const word[SIZE#0]) x_start#0 x_start = { (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $1e, (byte/signed byte/word/signed word/dword/signed dword) $1e }
(signed byte[SIZE#0]) y_add
(const signed byte[SIZE#0]) y_add#0 y_add = { fill( SIZE#0, 0) }
(word[SIZE#0]) y_cur
(const word[SIZE#0]) y_cur#0 y_cur = { fill( SIZE#0, 0) }
(byte[SIZE#0]) y_end
(const byte[SIZE#0]) y_end#0 y_end = { (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $14, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14 }
(byte[SIZE#0]) y_start
(const byte[SIZE#0]) y_start#0 y_start = { (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $a, (byte/signed byte/word/signed word/dword/signed dword) $14 }
zp ZP_BYTE:2 [ main::i#2 main::i#1 point_init::point_idx#0 screen_fill::y#4 screen_fill::y#1 bitmap_clear::y#4 bitmap_clear::y#1 bitmap_init::$3 ]
zp ZP_WORD:3 [ point_init::abs16s1_return#2 point_init::abs16s1_return#5 point_init::abs16s1_return#6 point_init::abs16s1_$2#0 divr16s::dividendu#3 divr16u::dividend#2 divr16u::dividend#1 divr16u::dividend#0 screen_fill::screen#2 screen_fill::screen#3 screen_fill::screen#1 bitmap_clear::bitmap#2 bitmap_clear::bitmap#3 bitmap_clear::bitmap#5 bitmap_clear::bitmap#1 bitmap_clear::$3 bitmap_init::yoffs#2 bitmap_init::yoffs#4 bitmap_init::yoffs#1 bitmap_plot::x#0 point_init::$4 point_init::$9 point_init::$10 point_init::$11 ]
@ -313,7 +315,7 @@ reg byte x [ bitmap_clear::x#2 bitmap_clear::x#1 ]
reg byte a [ bitmap_init::bits#3 bitmap_init::bits#4 bitmap_init::bits#1 ]
reg byte x [ bitmap_init::x#2 bitmap_init::x#1 ]
reg byte x [ bitmap_init::y#2 bitmap_init::y#1 ]
reg byte a [ main::$12 ]
reg byte a [ main::$13 ]
reg byte x [ bitmap_plot::y#0 ]
reg byte a [ bitmap_plot::$2 ]
reg byte x [ point_init::$18 ]

View File

@ -0,0 +1,25 @@
// Demonstrates global directive reserving addresses on zeropage
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
.label SCREEN = $400
.label i = 6
lda #0
sta i
b1:
lda i
jsr sub1
ldy i
sta SCREEN,y
inc i
lda #3
cmp i
bne b1
rts
}
// sub1(byte register(A) i)
sub1: {
asl
rts
}

View 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()
main: scope:[main] from @1
[4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) main::i#1 ← ++ (byte) main::i#2
[12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[13] return
to:@return
sub1: scope:[sub1] from main::@1
[14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[15] return
to:@return

View File

@ -0,0 +1,467 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@2
main: scope:[main] from @2
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@3
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 )
(byte) sub1::i#0 ← (byte) main::i#2
call sub1
(byte) sub1::return#0 ← (byte) sub1::return#2
to:main::@3
main::@3: scope:[main] from main::@1
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
(byte) sub1::return#3 ← phi( main::@1/(byte) sub1::return#0 )
(byte~) main::$0 ← (byte) sub1::return#3
*((byte*) main::SCREEN#0 + (byte) main::i#3) ← (byte~) main::$0
(byte) main::i#1 ← (byte) main::i#3 + rangenext(0,2)
(bool~) main::$1 ← (byte) main::i#1 != rangelast(0,2)
if((bool~) main::$1) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
return
to:@return
sub1: scope:[sub1] from main::@1
(byte) sub1::i#1 ← phi( main::@1/(byte) sub1::i#0 )
(byte~) sub1::$0 ← (byte) sub1::i#1 + (byte) sub1::i#1
(byte) sub1::return#1 ← (byte~) sub1::$0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
(byte) sub1::return#4 ← phi( sub1/(byte) sub1::return#1 )
(byte) sub1::return#2 ← (byte) sub1::return#4
return
to:@return
@2: scope:[] from @begin
call main
to:@3
@3: scope:[] from @2
to:@end
@end: scope:[] from @3
SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0
(bool~) main::$1
(label) main::@1
(label) main::@3
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte()) sub1((byte) sub1::i)
(byte~) sub1::$0
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0
(byte) sub1::i#1
(byte) sub1::return
(byte) sub1::return#0
(byte) sub1::return#1
(byte) sub1::return#2
(byte) sub1::return#3
(byte) sub1::return#4
Culled Empty Block (label) @3
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte) sub1::return#0 = (byte) sub1::return#3
Alias (byte) main::i#2 = (byte) main::i#3
Alias (byte) sub1::return#1 = (byte~) sub1::$0 (byte) sub1::return#4 (byte) sub1::return#2
Successful SSA optimization Pass2AliasElimination
Redundant Phi (byte) sub1::i#1 (byte) sub1::i#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$1 [11] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value if(main::i#1!=rangelast(0,2)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 3
Added new block during phi lifting main::@4(between main::@3 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Calls in [main] to sub1:8
Created 1 initial phi equivalence classes
Coalesced [5] main::i#4 ← main::i#0
Coalesced [15] main::i#5 ← main::i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) main::@4
Renumbering block @2 to @1
Renumbering block main::@3 to main::@2
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::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) main::i#1 ← ++ (byte) main::i#2
[12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[13] return
to:@return
sub1: scope:[sub1] from main::@1
[14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[15] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte~) main::$0 22.0
(byte*) main::SCREEN
(byte) main::i
(byte) main::i#0 4.0
(byte) main::i#1 16.5
(byte) main::i#2 7.666666666666666
(byte()) sub1((byte) sub1::i)
(byte) sub1::i
(byte) sub1::i#0 15.0
(byte) sub1::return
(byte) sub1::return#0 22.0
(byte) sub1::return#1 4.333333333333333
Initial phi equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
Added variable sub1::i#0 to zero page equivalence class [ sub1::i#0 ]
Added variable sub1::return#0 to zero page equivalence class [ sub1::return#0 ]
Added variable main::$0 to zero page equivalence class [ main::$0 ]
Added variable sub1::return#1 to zero page equivalence class [ sub1::return#1 ]
Complete equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
[ sub1::i#0 ]
[ sub1::return#0 ]
[ main::$0 ]
[ sub1::return#1 ]
Allocated zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ]
Allocated zp ZP_BYTE:7 [ sub1::i#0 ]
Allocated zp ZP_BYTE:8 [ sub1::return#0 ]
Allocated zp ZP_BYTE:9 [ main::$0 ]
Allocated zp ZP_BYTE:10 [ sub1::return#1 ]
INITIAL ASM
//SEG0 File Comments
// Demonstrates global directive reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label _0 = 9
.label i = 6
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
b1_from_main:
b1_from_b2:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuz1=vbuz2
lda i
sta sub1.i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1 -- vbuz1=vbuz2
lda sub1.return_1
sta sub1.return
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0 -- vbuz1=vbuz2
lda sub1.return
sta _0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2
lda _0
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b2
jmp breturn
//SEG22 main::@return
breturn:
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte zeropage(7) i)
sub1: {
.label i = 7
.label return = 8
.label return_1 = $a
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda i
asl
sta return_1
jmp breturn
//SEG26 sub1::@return
breturn:
//SEG27 [15] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#0 ] ( main:2 [ main::i#0 ] ) always clobbers reg byte a
Statement [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a
Statement [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:7 [ main::i#2 sub1::return#1 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ] : zp ZP_BYTE:6 ,
Potential registers zp ZP_BYTE:7 [ sub1::i#0 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:8 [ sub1::return#0 ] : zp ZP_BYTE:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:9 [ main::$0 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:10 [ sub1::return#1 ] : zp ZP_BYTE:10 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 28.17: zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ] 22: zp ZP_BYTE:9 [ main::$0 ]
Uplift Scope [sub1] 22: zp ZP_BYTE:8 [ sub1::return#0 ] 15: zp ZP_BYTE:7 [ sub1::i#0 ] 4.33: zp ZP_BYTE:10 [ sub1::return#1 ]
Uplift Scope []
Uplifting [main] best 545 combination zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ] reg byte a [ main::$0 ]
Uplifting [sub1] best 419 combination reg byte a [ sub1::return#0 ] reg byte a [ sub1::i#0 ] reg byte a [ sub1::return#1 ]
Uplifting [] best 419 combination
Attempting to uplift remaining variables inzp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ]
Uplifting [main] best 419 combination zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Demonstrates global directive reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 6
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
b1_from_main:
b1_from_b2:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b2
jmp breturn
//SEG22 main::@return
breturn:
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte register(A) i)
sub1: {
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
jmp breturn
//SEG26 sub1::@return
breturn:
//SEG27 [15] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b2 with b1
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction b1_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction b2:
Removing instruction breturn:
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
(void()) main()
(byte~) main::$0 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:6 4.0
(byte) main::i#1 i zp ZP_BYTE:6 16.5
(byte) main::i#2 i zp ZP_BYTE:6 7.666666666666666
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]
FINAL ASSEMBLER
Score: 314
//SEG0 File Comments
// Demonstrates global directive reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 6
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
//SEG17 main::@2
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1
//SEG22 main::@return
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte register(A) i)
sub1: {
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
//SEG26 sub1::@return
//SEG27 [15] return
rts
}

View File

@ -0,0 +1,27 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:6 4.0
(byte) main::i#1 i zp ZP_BYTE:6 16.5
(byte) main::i#2 i zp ZP_BYTE:6 7.666666666666666
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:6 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]

View File

@ -0,0 +1,25 @@
// Demonstrates a procedure reserving addresses on zeropage
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
.label SCREEN = $400
.label i = 5
lda #0
sta i
b1:
lda i
jsr sub1
ldy i
sta SCREEN,y
inc i
lda #3
cmp i
bne b1
rts
}
// sub1(byte register(A) i)
sub1: {
asl
rts
}

View 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()
main: scope:[main] from @1
[4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) main::i#1 ← ++ (byte) main::i#2
[12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[13] return
to:@return
sub1: scope:[sub1] from main::@1
[14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[15] return
to:@return

View File

@ -0,0 +1,467 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@2
main: scope:[main] from @2
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@3
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 )
(byte) sub1::i#0 ← (byte) main::i#2
call sub1
(byte) sub1::return#0 ← (byte) sub1::return#2
to:main::@3
main::@3: scope:[main] from main::@1
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
(byte) sub1::return#3 ← phi( main::@1/(byte) sub1::return#0 )
(byte~) main::$0 ← (byte) sub1::return#3
*((byte*) main::SCREEN#0 + (byte) main::i#3) ← (byte~) main::$0
(byte) main::i#1 ← (byte) main::i#3 + rangenext(0,2)
(bool~) main::$1 ← (byte) main::i#1 != rangelast(0,2)
if((bool~) main::$1) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
return
to:@return
sub1: scope:[sub1] from main::@1
(byte) sub1::i#1 ← phi( main::@1/(byte) sub1::i#0 )
(byte~) sub1::$0 ← (byte) sub1::i#1 + (byte) sub1::i#1
(byte) sub1::return#1 ← (byte~) sub1::$0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
(byte) sub1::return#4 ← phi( sub1/(byte) sub1::return#1 )
(byte) sub1::return#2 ← (byte) sub1::return#4
return
to:@return
@2: scope:[] from @begin
call main
to:@3
@3: scope:[] from @2
to:@end
@end: scope:[] from @3
SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0
(bool~) main::$1
(label) main::@1
(label) main::@3
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte()) sub1((byte) sub1::i)
(byte~) sub1::$0
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0
(byte) sub1::i#1
(byte) sub1::return
(byte) sub1::return#0
(byte) sub1::return#1
(byte) sub1::return#2
(byte) sub1::return#3
(byte) sub1::return#4
Culled Empty Block (label) @3
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte) sub1::return#0 = (byte) sub1::return#3
Alias (byte) main::i#2 = (byte) main::i#3
Alias (byte) sub1::return#1 = (byte~) sub1::$0 (byte) sub1::return#4 (byte) sub1::return#2
Successful SSA optimization Pass2AliasElimination
Redundant Phi (byte) sub1::i#1 (byte) sub1::i#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$1 [11] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value if(main::i#1!=rangelast(0,2)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 3
Added new block during phi lifting main::@4(between main::@3 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Calls in [main] to sub1:8
Created 1 initial phi equivalence classes
Coalesced [5] main::i#4 ← main::i#0
Coalesced [15] main::i#5 ← main::i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) main::@4
Renumbering block @2 to @1
Renumbering block main::@3 to main::@2
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::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) main::i#1 ← ++ (byte) main::i#2
[12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[13] return
to:@return
sub1: scope:[sub1] from main::@1
[14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[15] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte~) main::$0 22.0
(byte*) main::SCREEN
(byte) main::i
(byte) main::i#0 4.0
(byte) main::i#1 16.5
(byte) main::i#2 7.666666666666666
(byte()) sub1((byte) sub1::i)
(byte) sub1::i
(byte) sub1::i#0 15.0
(byte) sub1::return
(byte) sub1::return#0 22.0
(byte) sub1::return#1 4.333333333333333
Initial phi equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
Added variable sub1::i#0 to zero page equivalence class [ sub1::i#0 ]
Added variable sub1::return#0 to zero page equivalence class [ sub1::return#0 ]
Added variable main::$0 to zero page equivalence class [ main::$0 ]
Added variable sub1::return#1 to zero page equivalence class [ sub1::return#1 ]
Complete equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
[ sub1::i#0 ]
[ sub1::return#0 ]
[ main::$0 ]
[ sub1::return#1 ]
Allocated zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
Allocated zp ZP_BYTE:6 [ sub1::i#0 ]
Allocated zp ZP_BYTE:7 [ sub1::return#0 ]
Allocated zp ZP_BYTE:8 [ main::$0 ]
Allocated zp ZP_BYTE:9 [ sub1::return#1 ]
INITIAL ASM
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label _0 = 8
.label i = 5
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
b1_from_main:
b1_from_b2:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuz1=vbuz2
lda i
sta sub1.i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1 -- vbuz1=vbuz2
lda sub1.return_1
sta sub1.return
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0 -- vbuz1=vbuz2
lda sub1.return
sta _0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2
lda _0
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b2
jmp breturn
//SEG22 main::@return
breturn:
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte zeropage(6) i)
sub1: {
.label i = 6
.label return = 7
.label return_1 = 9
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda i
asl
sta return_1
jmp breturn
//SEG26 sub1::@return
breturn:
//SEG27 [15] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#0 ] ( main:2 [ main::i#0 ] ) always clobbers reg byte a
Statement [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a
Statement [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:7 [ main::i#2 sub1::return#1 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ] : zp ZP_BYTE:5 ,
Potential registers zp ZP_BYTE:6 [ sub1::i#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:7 [ sub1::return#0 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:8 [ main::$0 ] : zp ZP_BYTE:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:9 [ sub1::return#1 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 28.17: zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ] 22: zp ZP_BYTE:8 [ main::$0 ]
Uplift Scope [sub1] 22: zp ZP_BYTE:7 [ sub1::return#0 ] 15: zp ZP_BYTE:6 [ sub1::i#0 ] 4.33: zp ZP_BYTE:9 [ sub1::return#1 ]
Uplift Scope []
Uplifting [main] best 545 combination zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ] reg byte a [ main::$0 ]
Uplifting [sub1] best 419 combination reg byte a [ sub1::return#0 ] reg byte a [ sub1::i#0 ] reg byte a [ sub1::return#1 ]
Uplifting [] best 419 combination
Attempting to uplift remaining variables inzp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
Uplifting [main] best 419 combination zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 5
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
b1_from_main:
b1_from_b2:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b2
jmp breturn
//SEG22 main::@return
breturn:
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte register(A) i)
sub1: {
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
jmp breturn
//SEG26 sub1::@return
breturn:
//SEG27 [15] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b2 with b1
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction b1_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction b2:
Removing instruction breturn:
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
(void()) main()
(byte~) main::$0 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:5 4.0
(byte) main::i#1 i zp ZP_BYTE:5 16.5
(byte) main::i#2 i zp ZP_BYTE:5 7.666666666666666
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]
FINAL ASSEMBLER
Score: 314
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 5
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
//SEG17 main::@2
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1
//SEG22 main::@return
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte register(A) i)
sub1: {
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
//SEG26 sub1::@return
//SEG27 [15] return
rts
}

View File

@ -0,0 +1,27 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:5 4.0
(byte) main::i#1 i zp ZP_BYTE:5 16.5
(byte) main::i#2 i zp ZP_BYTE:5 7.666666666666666
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]

View File

@ -0,0 +1,38 @@
// Demonstrates a procedure reserving addresses on zeropage
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
.label SCREEN = $400
.label i = 8
lda #0
sta i
b1:
lda i
jsr sub1
ldy i
sta SCREEN,y
ldx i
jsr sub2
ldy i
sta SCREEN+$28,y
inc i
lda #3
cmp i
bne b1
rts
}
// sub2(byte register(X) i)
sub2: {
txa
asl
stx $ff
clc
adc $ff
rts
}
// sub1(byte register(A) i)
sub1: {
asl
rts
}

View File

@ -0,0 +1,47 @@
@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::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) sub2::i#0 ← (byte) main::i#2
[12] call sub2
[13] (byte) sub2::return#0 ← (byte) sub2::return#1
to:main::@3
main::@3: scope:[main] from main::@2
[14] (byte~) main::$2 ← (byte) sub2::return#0
[15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2
[16] (byte) main::i#1 ← ++ (byte) main::i#2
[17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
[18] return
to:@return
sub2: scope:[sub2] from main::@2
[19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0
[20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0
to:sub2::@return
sub2::@return: scope:[sub2] from sub2
[21] return
to:@return
sub1: scope:[sub1] from main::@1
[22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[23] return
to:@return

View File

@ -0,0 +1,681 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@3
main: scope:[main] from @3
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@4
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@4/(byte) main::i#1 )
(byte) sub1::i#0 ← (byte) main::i#2
call sub1
(byte) sub1::return#0 ← (byte) sub1::return#2
to:main::@3
main::@3: scope:[main] from main::@1
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
(byte) sub1::return#3 ← phi( main::@1/(byte) sub1::return#0 )
(byte~) main::$0 ← (byte) sub1::return#3
*((byte*) main::SCREEN#0 + (byte) main::i#3) ← (byte~) main::$0
(byte*~) main::$1 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) $28
(byte) sub2::i#0 ← (byte) main::i#3
call sub2
(byte) sub2::return#0 ← (byte) sub2::return#2
to:main::@4
main::@4: scope:[main] from main::@3
(byte) main::i#4 ← phi( main::@3/(byte) main::i#3 )
(byte) sub2::return#3 ← phi( main::@3/(byte) sub2::return#0 )
(byte~) main::$2 ← (byte) sub2::return#3
*((byte*~) main::$1 + (byte) main::i#4) ← (byte~) main::$2
(byte) main::i#1 ← (byte) main::i#4 + rangenext(0,2)
(bool~) main::$3 ← (byte) main::i#1 != rangelast(0,2)
if((bool~) main::$3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@4
return
to:@return
sub1: scope:[sub1] from main::@1
(byte) sub1::i#1 ← phi( main::@1/(byte) sub1::i#0 )
(byte~) sub1::$0 ← (byte) sub1::i#1 + (byte) sub1::i#1
(byte) sub1::return#1 ← (byte~) sub1::$0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
(byte) sub1::return#4 ← phi( sub1/(byte) sub1::return#1 )
(byte) sub1::return#2 ← (byte) sub1::return#4
return
to:@return
sub2: scope:[sub2] from main::@3
(byte) sub2::i#1 ← phi( main::@3/(byte) sub2::i#0 )
(byte~) sub2::$0 ← (byte) sub2::i#1 + (byte) sub2::i#1
(byte~) sub2::$1 ← (byte~) sub2::$0 + (byte) sub2::i#1
(byte) sub2::return#1 ← (byte~) sub2::$1
to:sub2::@return
sub2::@return: scope:[sub2] from sub2
(byte) sub2::return#4 ← phi( sub2/(byte) sub2::return#1 )
(byte) sub2::return#2 ← (byte) sub2::return#4
return
to:@return
@3: scope:[] from @begin
call main
to:@4
@4: scope:[] from @3
to:@end
@end: scope:[] from @4
SYMBOL TABLE SSA
(label) @3
(label) @4
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0
(byte*~) main::$1
(byte~) main::$2
(bool~) main::$3
(label) main::@1
(label) main::@3
(label) main::@4
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte) main::i#4
(byte()) sub1((byte) sub1::i)
(byte~) sub1::$0
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0
(byte) sub1::i#1
(byte) sub1::return
(byte) sub1::return#0
(byte) sub1::return#1
(byte) sub1::return#2
(byte) sub1::return#3
(byte) sub1::return#4
(byte()) sub2((byte) sub2::i)
(byte~) sub2::$0
(byte~) sub2::$1
(label) sub2::@return
(byte) sub2::i
(byte) sub2::i#0
(byte) sub2::i#1
(byte) sub2::return
(byte) sub2::return#0
(byte) sub2::return#1
(byte) sub2::return#2
(byte) sub2::return#3
(byte) sub2::return#4
Culled Empty Block (label) @4
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte) sub1::return#0 = (byte) sub1::return#3
Alias (byte) main::i#2 = (byte) main::i#3 (byte) main::i#4
Alias (byte) sub2::return#0 = (byte) sub2::return#3
Alias (byte) sub1::return#1 = (byte~) sub1::$0 (byte) sub1::return#4 (byte) sub1::return#2
Alias (byte) sub2::return#1 = (byte~) sub2::$1 (byte) sub2::return#4 (byte) sub2::return#2
Successful SSA optimization Pass2AliasElimination
Redundant Phi (byte) sub1::i#1 (byte) sub1::i#0
Redundant Phi (byte) sub2::i#1 (byte) sub2::i#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$3 [18] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte*) main::$1 = main::SCREEN#0+$28
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value if(main::i#1!=rangelast(0,2)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 3
Constant inlined main::$1 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@5(between main::@4 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Calls in [main] to sub1:8 sub2:13
Created 1 initial phi equivalence classes
Coalesced [5] main::i#5 ← main::i#0
Coalesced [20] main::i#6 ← main::i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) main::@5
Renumbering block @3 to @1
Renumbering block main::@3 to main::@2
Renumbering block main::@4 to main::@3
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::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) sub2::i#0 ← (byte) main::i#2
[12] call sub2
[13] (byte) sub2::return#0 ← (byte) sub2::return#1
to:main::@3
main::@3: scope:[main] from main::@2
[14] (byte~) main::$2 ← (byte) sub2::return#0
[15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2
[16] (byte) main::i#1 ← ++ (byte) main::i#2
[17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
[18] return
to:@return
sub2: scope:[sub2] from main::@2
[19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0
[20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0
to:sub2::@return
sub2::@return: scope:[sub2] from sub2
[21] return
to:@return
sub1: scope:[sub1] from main::@1
[22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[23] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte~) main::$0 22.0
(byte~) main::$2 22.0
(byte*) main::SCREEN
(byte) main::i
(byte) main::i#0 4.0
(byte) main::i#1 16.5
(byte) main::i#2 6.181818181818182
(byte()) sub1((byte) sub1::i)
(byte) sub1::i
(byte) sub1::i#0 15.0
(byte) sub1::return
(byte) sub1::return#0 22.0
(byte) sub1::return#1 4.333333333333333
(byte()) sub2((byte) sub2::i)
(byte~) sub2::$0 4.0
(byte) sub2::i
(byte) sub2::i#0 8.5
(byte) sub2::return
(byte) sub2::return#0 22.0
(byte) sub2::return#1 4.333333333333333
Initial phi equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
Added variable sub1::i#0 to zero page equivalence class [ sub1::i#0 ]
Added variable sub1::return#0 to zero page equivalence class [ sub1::return#0 ]
Added variable main::$0 to zero page equivalence class [ main::$0 ]
Added variable sub2::i#0 to zero page equivalence class [ sub2::i#0 ]
Added variable sub2::return#0 to zero page equivalence class [ sub2::return#0 ]
Added variable main::$2 to zero page equivalence class [ main::$2 ]
Added variable sub2::$0 to zero page equivalence class [ sub2::$0 ]
Added variable sub2::return#1 to zero page equivalence class [ sub2::return#1 ]
Added variable sub1::return#1 to zero page equivalence class [ sub1::return#1 ]
Complete equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
[ sub1::i#0 ]
[ sub1::return#0 ]
[ main::$0 ]
[ sub2::i#0 ]
[ sub2::return#0 ]
[ main::$2 ]
[ sub2::$0 ]
[ sub2::return#1 ]
[ sub1::return#1 ]
Allocated zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ]
Allocated zp ZP_BYTE:9 [ sub1::i#0 ]
Allocated zp ZP_BYTE:10 [ sub1::return#0 ]
Allocated zp ZP_BYTE:11 [ main::$0 ]
Allocated zp ZP_BYTE:12 [ sub2::i#0 ]
Allocated zp ZP_BYTE:13 [ sub2::return#0 ]
Allocated zp ZP_BYTE:14 [ main::$2 ]
Allocated zp ZP_BYTE:15 [ sub2::$0 ]
Allocated zp ZP_BYTE:16 [ sub2::return#1 ]
Allocated zp ZP_BYTE:17 [ sub1::return#1 ]
INITIAL ASM
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label _0 = $b
.label _2 = $e
.label i = 8
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@3 to main::@1 [phi:main/main::@3->main::@1]
b1_from_main:
b1_from_b3:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@3->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuz1=vbuz2
lda i
sta sub1.i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1 -- vbuz1=vbuz2
lda sub1.return_1
sta sub1.return
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0 -- vbuz1=vbuz2
lda sub1.return
sta _0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2
lda _0
ldy i
sta SCREEN,y
//SEG20 [11] (byte) sub2::i#0 ← (byte) main::i#2 -- vbuz1=vbuz2
lda i
sta sub2.i
//SEG21 [12] call sub2
jsr sub2
//SEG22 [13] (byte) sub2::return#0 ← (byte) sub2::return#1 -- vbuz1=vbuz2
lda sub2.return_1
sta sub2.return
jmp b3
//SEG23 main::@3
b3:
//SEG24 [14] (byte~) main::$2 ← (byte) sub2::return#0 -- vbuz1=vbuz2
lda sub2.return
sta _2
//SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuz2
lda _2
ldy i
sta SCREEN+$28,y
//SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b3
jmp breturn
//SEG28 main::@return
breturn:
//SEG29 [18] return
rts
}
//SEG30 sub2
// sub2(byte zeropage($c) i)
sub2: {
.label _0 = $f
.label i = $c
.label return = $d
.label return_1 = $10
//SEG31 [19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda i
asl
sta _0
//SEG32 [20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0 -- vbuz1=vbuz2_plus_vbuz3
lda _0
clc
adc i
sta return_1
jmp breturn
//SEG33 sub2::@return
breturn:
//SEG34 [21] return
rts
}
//SEG35 sub1
// sub1(byte zeropage(9) i)
sub1: {
.label i = 9
.label return = $a
.label return_1 = $11
//SEG36 [22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda i
asl
sta return_1
jmp breturn
//SEG37 sub1::@return
breturn:
//SEG38 [23] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#0 ] ( main:2 [ main::i#0 ] ) always clobbers reg byte a
Statement [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a
Statement [19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0 [ sub2::i#0 sub2::$0 ] ( main:2::sub2:12 [ main::i#2 sub2::i#0 sub2::$0 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:12 [ sub2::i#0 ]
Statement [20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0 [ sub2::return#1 ] ( main:2::sub2:12 [ main::i#2 sub2::return#1 ] ) always clobbers reg byte a
Statement [22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:7 [ main::i#2 sub1::return#1 ] ) always clobbers reg byte a
Statement [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#0 ] ( main:2 [ main::i#0 ] ) always clobbers reg byte a
Statement [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a
Statement [19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0 [ sub2::i#0 sub2::$0 ] ( main:2::sub2:12 [ main::i#2 sub2::i#0 sub2::$0 ] ) always clobbers reg byte a
Statement [20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0 [ sub2::return#1 ] ( main:2::sub2:12 [ main::i#2 sub2::return#1 ] ) always clobbers reg byte a
Statement [22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:7 [ main::i#2 sub1::return#1 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ] : zp ZP_BYTE:8 ,
Potential registers zp ZP_BYTE:9 [ sub1::i#0 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:10 [ sub1::return#0 ] : zp ZP_BYTE:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:11 [ main::$0 ] : zp ZP_BYTE:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:12 [ sub2::i#0 ] : zp ZP_BYTE:12 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:13 [ sub2::return#0 ] : zp ZP_BYTE:13 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:14 [ main::$2 ] : zp ZP_BYTE:14 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:15 [ sub2::$0 ] : zp ZP_BYTE:15 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:16 [ sub2::return#1 ] : zp ZP_BYTE:16 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:17 [ sub1::return#1 ] : zp ZP_BYTE:17 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 26.68: zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ] 22: zp ZP_BYTE:11 [ main::$0 ] 22: zp ZP_BYTE:14 [ main::$2 ]
Uplift Scope [sub1] 22: zp ZP_BYTE:10 [ sub1::return#0 ] 15: zp ZP_BYTE:9 [ sub1::i#0 ] 4.33: zp ZP_BYTE:17 [ sub1::return#1 ]
Uplift Scope [sub2] 22: zp ZP_BYTE:13 [ sub2::return#0 ] 8.5: zp ZP_BYTE:12 [ sub2::i#0 ] 4.33: zp ZP_BYTE:16 [ sub2::return#1 ] 4: zp ZP_BYTE:15 [ sub2::$0 ]
Uplift Scope []
Uplifting [main] best 893 combination zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ] reg byte a [ main::$0 ] reg byte a [ main::$2 ]
Uplifting [sub1] best 767 combination reg byte a [ sub1::return#0 ] reg byte a [ sub1::i#0 ] reg byte a [ sub1::return#1 ]
Uplifting [sub2] best 640 combination reg byte a [ sub2::return#0 ] reg byte x [ sub2::i#0 ] reg byte a [ sub2::return#1 ] reg byte a [ sub2::$0 ]
Limited combination testing to 100 combinations of 192 possible.
Uplifting [] best 640 combination
Attempting to uplift remaining variables inzp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ]
Uplifting [main] best 640 combination zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 8
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@3 to main::@1 [phi:main/main::@3->main::@1]
b1_from_main:
b1_from_b3:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@3->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) sub2::i#0 ← (byte) main::i#2 -- vbuxx=vbuz1
ldx i
//SEG21 [12] call sub2
jsr sub2
//SEG22 [13] (byte) sub2::return#0 ← (byte) sub2::return#1
jmp b3
//SEG23 main::@3
b3:
//SEG24 [14] (byte~) main::$2 ← (byte) sub2::return#0
//SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN+$28,y
//SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b3
jmp breturn
//SEG28 main::@return
breturn:
//SEG29 [18] return
rts
}
//SEG30 sub2
// sub2(byte register(X) i)
sub2: {
//SEG31 [19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0 -- vbuaa=vbuxx_plus_vbuxx
txa
asl
//SEG32 [20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0 -- vbuaa=vbuaa_plus_vbuxx
stx $ff
clc
adc $ff
jmp breturn
//SEG33 sub2::@return
breturn:
//SEG34 [21] return
rts
}
//SEG35 sub1
// sub1(byte register(A) i)
sub1: {
//SEG36 [22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
jmp breturn
//SEG37 sub1::@return
breturn:
//SEG38 [23] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp b3
Removing instruction jmp breturn
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b3 with b1
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction b1_from_b3:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction b2:
Removing instruction b3:
Removing instruction breturn:
Removing instruction breturn:
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
(void()) main()
(byte~) main::$0 reg byte a 22.0
(byte~) main::$2 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:8 4.0
(byte) main::i#1 i zp ZP_BYTE:8 16.5
(byte) main::i#2 i zp ZP_BYTE:8 6.181818181818182
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
(byte()) sub2((byte) sub2::i)
(byte~) sub2::$0 reg byte a 4.0
(label) sub2::@return
(byte) sub2::i
(byte) sub2::i#0 reg byte x 8.5
(byte) sub2::return
(byte) sub2::return#0 reg byte a 22.0
(byte) sub2::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte x [ sub2::i#0 ]
reg byte a [ sub2::return#0 ]
reg byte a [ main::$2 ]
reg byte a [ sub2::$0 ]
reg byte a [ sub2::return#1 ]
reg byte a [ sub1::return#1 ]
FINAL ASSEMBLER
Score: 502
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 8
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@3 to main::@1 [phi:main/main::@3->main::@1]
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@3->main::@1#0] -- register_copy
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
//SEG17 main::@2
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) sub2::i#0 ← (byte) main::i#2 -- vbuxx=vbuz1
ldx i
//SEG21 [12] call sub2
jsr sub2
//SEG22 [13] (byte) sub2::return#0 ← (byte) sub2::return#1
//SEG23 main::@3
//SEG24 [14] (byte~) main::$2 ← (byte) sub2::return#0
//SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN+$28,y
//SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1
//SEG28 main::@return
//SEG29 [18] return
rts
}
//SEG30 sub2
// sub2(byte register(X) i)
sub2: {
//SEG31 [19] (byte~) sub2::$0 ← (byte) sub2::i#0 + (byte) sub2::i#0 -- vbuaa=vbuxx_plus_vbuxx
txa
asl
//SEG32 [20] (byte) sub2::return#1 ← (byte~) sub2::$0 + (byte) sub2::i#0 -- vbuaa=vbuaa_plus_vbuxx
stx $ff
clc
adc $ff
//SEG33 sub2::@return
//SEG34 [21] return
rts
}
//SEG35 sub1
// sub1(byte register(A) i)
sub1: {
//SEG36 [22] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
//SEG37 sub1::@return
//SEG38 [23] return
rts
}

View File

@ -0,0 +1,42 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 22.0
(byte~) main::$2 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:8 4.0
(byte) main::i#1 i zp ZP_BYTE:8 16.5
(byte) main::i#2 i zp ZP_BYTE:8 6.181818181818182
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
(byte()) sub2((byte) sub2::i)
(byte~) sub2::$0 reg byte a 4.0
(label) sub2::@return
(byte) sub2::i
(byte) sub2::i#0 reg byte x 8.5
(byte) sub2::return
(byte) sub2::return#0 reg byte a 22.0
(byte) sub2::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:8 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte x [ sub2::i#0 ]
reg byte a [ sub2::return#0 ]
reg byte a [ main::$2 ]
reg byte a [ sub2::$0 ]
reg byte a [ sub2::return#1 ]
reg byte a [ sub1::return#1 ]

View File

@ -0,0 +1,25 @@
// Demonstrates a procedure reserving addresses on zeropage
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
.label SCREEN = $400
.label i = 5
lda #0
sta i
b1:
lda i
jsr sub1
ldy i
sta SCREEN,y
inc i
lda #3
cmp i
bne b1
rts
}
// sub1(byte register(A) i)
sub1: {
asl
rts
}

View 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()
main: scope:[main] from @1
[4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) main::i#1 ← ++ (byte) main::i#2
[12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[13] return
to:@return
sub1: scope:[sub1] from main::@1
[14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[15] return
to:@return

View File

@ -0,0 +1,467 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@3
main: scope:[main] from @3
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@3
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 )
(byte) sub1::i#0 ← (byte) main::i#2
call sub1
(byte) sub1::return#0 ← (byte) sub1::return#2
to:main::@3
main::@3: scope:[main] from main::@1
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
(byte) sub1::return#3 ← phi( main::@1/(byte) sub1::return#0 )
(byte~) main::$0 ← (byte) sub1::return#3
*((byte*) main::SCREEN#0 + (byte) main::i#3) ← (byte~) main::$0
(byte) main::i#1 ← (byte) main::i#3 + rangenext(0,2)
(bool~) main::$1 ← (byte) main::i#1 != rangelast(0,2)
if((bool~) main::$1) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
return
to:@return
sub1: scope:[sub1] from main::@1
(byte) sub1::i#1 ← phi( main::@1/(byte) sub1::i#0 )
(byte~) sub1::$0 ← (byte) sub1::i#1 + (byte) sub1::i#1
(byte) sub1::return#1 ← (byte~) sub1::$0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
(byte) sub1::return#4 ← phi( sub1/(byte) sub1::return#1 )
(byte) sub1::return#2 ← (byte) sub1::return#4
return
to:@return
@3: scope:[] from @begin
call main
to:@4
@4: scope:[] from @3
to:@end
@end: scope:[] from @4
SYMBOL TABLE SSA
(label) @3
(label) @4
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0
(bool~) main::$1
(label) main::@1
(label) main::@3
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte()) sub1((byte) sub1::i)
(byte~) sub1::$0
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0
(byte) sub1::i#1
(byte) sub1::return
(byte) sub1::return#0
(byte) sub1::return#1
(byte) sub1::return#2
(byte) sub1::return#3
(byte) sub1::return#4
Culled Empty Block (label) @4
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte) sub1::return#0 = (byte) sub1::return#3
Alias (byte) main::i#2 = (byte) main::i#3
Alias (byte) sub1::return#1 = (byte~) sub1::$0 (byte) sub1::return#4 (byte) sub1::return#2
Successful SSA optimization Pass2AliasElimination
Redundant Phi (byte) sub1::i#1 (byte) sub1::i#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$1 [11] if((byte) main::i#1!=rangelast(0,2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) main::SCREEN#0 = ((byte*))$400
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value if(main::i#1!=rangelast(0,2)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 3
Added new block during phi lifting main::@4(between main::@3 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Calls in [main] to sub1:8
Created 1 initial phi equivalence classes
Coalesced [5] main::i#4 ← main::i#0
Coalesced [15] main::i#5 ← main::i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) main::@4
Renumbering block @3 to @1
Renumbering block main::@3 to main::@2
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::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
[6] (byte) sub1::i#0 ← (byte) main::i#2
[7] call sub1
[8] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[9] (byte~) main::$0 ← (byte) sub1::return#0
[10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0
[11] (byte) main::i#1 ← ++ (byte) main::i#2
[12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[13] return
to:@return
sub1: scope:[sub1] from main::@1
[14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[15] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte~) main::$0 22.0
(byte*) main::SCREEN
(byte) main::i
(byte) main::i#0 4.0
(byte) main::i#1 16.5
(byte) main::i#2 7.666666666666666
(byte()) sub1((byte) sub1::i)
(byte) sub1::i
(byte) sub1::i#0 15.0
(byte) sub1::return
(byte) sub1::return#0 22.0
(byte) sub1::return#1 4.333333333333333
Initial phi equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
Added variable sub1::i#0 to zero page equivalence class [ sub1::i#0 ]
Added variable sub1::return#0 to zero page equivalence class [ sub1::return#0 ]
Added variable main::$0 to zero page equivalence class [ main::$0 ]
Added variable sub1::return#1 to zero page equivalence class [ sub1::return#1 ]
Complete equivalence classes
[ main::i#2 main::i#0 main::i#1 ]
[ sub1::i#0 ]
[ sub1::return#0 ]
[ main::$0 ]
[ sub1::return#1 ]
Allocated zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
Allocated zp ZP_BYTE:6 [ sub1::i#0 ]
Allocated zp ZP_BYTE:7 [ sub1::return#0 ]
Allocated zp ZP_BYTE:8 [ main::$0 ]
Allocated zp ZP_BYTE:9 [ sub1::return#1 ]
INITIAL ASM
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label _0 = 8
.label i = 5
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
b1_from_main:
b1_from_b2:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuz1=vbuz2
lda i
sta sub1.i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1 -- vbuz1=vbuz2
lda sub1.return_1
sta sub1.return
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0 -- vbuz1=vbuz2
lda sub1.return
sta _0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2
lda _0
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b2
jmp breturn
//SEG22 main::@return
breturn:
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte zeropage(6) i)
sub1: {
.label i = 6
.label return = 7
.label return_1 = 9
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda i
asl
sta return_1
jmp breturn
//SEG26 sub1::@return
breturn:
//SEG27 [15] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#0 ] ( main:2 [ main::i#0 ] ) always clobbers reg byte a
Statement [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte y
Statement [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a
Statement [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:7 [ main::i#2 sub1::return#1 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ] : zp ZP_BYTE:5 ,
Potential registers zp ZP_BYTE:6 [ sub1::i#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:7 [ sub1::return#0 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:8 [ main::$0 ] : zp ZP_BYTE:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:9 [ sub1::return#1 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 28.17: zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ] 22: zp ZP_BYTE:8 [ main::$0 ]
Uplift Scope [sub1] 22: zp ZP_BYTE:7 [ sub1::return#0 ] 15: zp ZP_BYTE:6 [ sub1::i#0 ] 4.33: zp ZP_BYTE:9 [ sub1::return#1 ]
Uplift Scope []
Uplifting [main] best 545 combination zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ] reg byte a [ main::$0 ]
Uplifting [sub1] best 419 combination reg byte a [ sub1::return#0 ] reg byte a [ sub1::i#0 ] reg byte a [ sub1::return#1 ]
Uplifting [] best 419 combination
Attempting to uplift remaining variables inzp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
Uplifting [main] best 419 combination zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 5
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
b1_from_main:
b1_from_b2:
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
jmp b2
//SEG17 main::@2
b2:
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1_from_b2
jmp breturn
//SEG22 main::@return
breturn:
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte register(A) i)
sub1: {
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
jmp breturn
//SEG26 sub1::@return
breturn:
//SEG27 [15] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b2 with b1
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction b1_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction b2:
Removing instruction breturn:
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
(void()) main()
(byte~) main::$0 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:5 4.0
(byte) main::i#1 i zp ZP_BYTE:5 16.5
(byte) main::i#2 i zp ZP_BYTE:5 7.666666666666666
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]
FINAL ASSEMBLER
Score: 314
//SEG0 File Comments
// Demonstrates a procedure reserving addresses on zeropage
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//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: {
.label SCREEN = $400
.label i = 5
//SEG10 [4] (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta i
//SEG11 [5] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1]
//SEG12 [5] phi (byte) main::i#2 = (byte) main::i#0 [phi:main/main::@2->main::@1#0] -- register_copy
//SEG13 main::@1
b1:
//SEG14 [6] (byte) sub1::i#0 ← (byte) main::i#2 -- vbuaa=vbuz1
lda i
//SEG15 [7] call sub1
jsr sub1
//SEG16 [8] (byte) sub1::return#0 ← (byte) sub1::return#1
//SEG17 main::@2
//SEG18 [9] (byte~) main::$0 ← (byte) sub1::return#0
//SEG19 [10] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy i
sta SCREEN,y
//SEG20 [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc i
//SEG21 [12] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp i
bne b1
//SEG22 main::@return
//SEG23 [13] return
rts
}
//SEG24 sub1
// sub1(byte register(A) i)
sub1: {
//SEG25 [14] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
//SEG26 sub1::@return
//SEG27 [15] return
rts
}

View File

@ -0,0 +1,27 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(byte) main::i
(byte) main::i#0 i zp ZP_BYTE:5 4.0
(byte) main::i#1 i zp ZP_BYTE:5 16.5
(byte) main::i#2 i zp ZP_BYTE:5 7.666666666666666
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 15.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 22.0
(byte) sub1::return#1 reg byte a 4.333333333333333
zp ZP_BYTE:5 [ main::i#2 main::i#0 main::i#1 ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]