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:
parent
fc79ac187e
commit
1ea5a3af76
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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> {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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]);
|
||||
}
|
||||
|
15
src/test/kc/reserve-zp-global.kc
Normal file
15
src/test/kc/reserve-zp-global.kc
Normal 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;
|
||||
}
|
||||
|
12
src/test/kc/reserve-zp-procedure-1.kc
Normal file
12
src/test/kc/reserve-zp-procedure-1.kc
Normal 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;
|
||||
}
|
17
src/test/kc/reserve-zp-procedure-2.kc
Normal file
17
src/test/kc/reserve-zp-procedure-2.kc
Normal 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;
|
||||
}
|
16
src/test/kc/reserve-zp-procedure-3.kc
Normal file
16
src/test/kc/reserve-zp-procedure-3.kc
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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
@ -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 ]
|
||||
|
25
src/test/ref/reserve-zp-global.asm
Normal file
25
src/test/ref/reserve-zp-global.asm
Normal 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
|
||||
}
|
33
src/test/ref/reserve-zp-global.cfg
Normal file
33
src/test/ref/reserve-zp-global.cfg
Normal file
@ -0,0 +1,33 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
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
|
467
src/test/ref/reserve-zp-global.log
Normal file
467
src/test/ref/reserve-zp-global.log
Normal 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
|
||||
}
|
||||
|
27
src/test/ref/reserve-zp-global.sym
Normal file
27
src/test/ref/reserve-zp-global.sym
Normal 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 ]
|
25
src/test/ref/reserve-zp-procedure-1.asm
Normal file
25
src/test/ref/reserve-zp-procedure-1.asm
Normal 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
|
||||
}
|
33
src/test/ref/reserve-zp-procedure-1.cfg
Normal file
33
src/test/ref/reserve-zp-procedure-1.cfg
Normal file
@ -0,0 +1,33 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
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
|
467
src/test/ref/reserve-zp-procedure-1.log
Normal file
467
src/test/ref/reserve-zp-procedure-1.log
Normal 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
|
||||
}
|
||||
|
27
src/test/ref/reserve-zp-procedure-1.sym
Normal file
27
src/test/ref/reserve-zp-procedure-1.sym
Normal 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 ]
|
38
src/test/ref/reserve-zp-procedure-2.asm
Normal file
38
src/test/ref/reserve-zp-procedure-2.asm
Normal 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
|
||||
}
|
47
src/test/ref/reserve-zp-procedure-2.cfg
Normal file
47
src/test/ref/reserve-zp-procedure-2.cfg
Normal 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
|
681
src/test/ref/reserve-zp-procedure-2.log
Normal file
681
src/test/ref/reserve-zp-procedure-2.log
Normal 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
|
||||
}
|
||||
|
42
src/test/ref/reserve-zp-procedure-2.sym
Normal file
42
src/test/ref/reserve-zp-procedure-2.sym
Normal 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 ]
|
25
src/test/ref/reserve-zp-procedure-3.asm
Normal file
25
src/test/ref/reserve-zp-procedure-3.asm
Normal 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
|
||||
}
|
33
src/test/ref/reserve-zp-procedure-3.cfg
Normal file
33
src/test/ref/reserve-zp-procedure-3.cfg
Normal file
@ -0,0 +1,33 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
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
|
467
src/test/ref/reserve-zp-procedure-3.log
Normal file
467
src/test/ref/reserve-zp-procedure-3.log
Normal 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
|
||||
}
|
||||
|
27
src/test/ref/reserve-zp-procedure-3.sym
Normal file
27
src/test/ref/reserve-zp-procedure-3.sym
Normal 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 ]
|
Loading…
Reference in New Issue
Block a user