1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-26 18:29:54 +00:00

Added support for reserving ZP ranges using NN..NN range syntax "#pragma zp_reserve(0x00..0x1f, 0x22). Changed name of #pragma and function directive to zp_reserve() and __zp_reserve(). Closes #238

This commit is contained in:
jespergravgaard 2020-05-22 15:24:03 +02:00
parent d714c6ab4c
commit 978d85055a
37 changed files with 3740 additions and 2454 deletions

View File

@ -62,7 +62,7 @@ ASSIGN_COMPOUND : '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '&=' | '|='
// Keywords // Keywords
TYPEDEF: 'typedef' ; TYPEDEF: 'typedef' ;
RESERVE:'reserve' ; RESERVE: 'zp_reserve' ;
PC:'pc'; PC:'pc';
TARGET:'target'; TARGET:'target';
LINK:'link'; LINK:'link';
@ -81,6 +81,7 @@ VOLATILE: 'volatile' ;
STATIC: 'static' ; STATIC: 'static' ;
INTERRUPT: 'interrupt' ; INTERRUPT: 'interrupt' ;
REGISTER: 'register' ; REGISTER: 'register' ;
LOCAL_RESERVE: '__zp_reserve' ;
ADDRESS: '__address' ; ADDRESS: '__address' ;
ADDRESS_ZEROPAGE: '__zp' ; ADDRESS_ZEROPAGE: '__zp' ;
ADDRESS_MAINMEM: '__mem' ; ADDRESS_MAINMEM: '__mem' ;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -56,111 +56,112 @@ VOLATILE=55
STATIC=56 STATIC=56
INTERRUPT=57 INTERRUPT=57
REGISTER=58 REGISTER=58
ADDRESS=59 LOCAL_RESERVE=59
ADDRESS_ZEROPAGE=60 ADDRESS=60
ADDRESS_MAINMEM=61 ADDRESS_ZEROPAGE=61
FORM_SSA=62 ADDRESS_MAINMEM=62
FORM_MA=63 FORM_SSA=63
INTRINSIC=64 FORM_MA=64
CALLING=65 INTRINSIC=65
CALLINGCONVENTION=66 CALLING=66
VARMODEL=67 CALLINGCONVENTION=67
IF=68 VARMODEL=68
ELSE=69 IF=69
WHILE=70 ELSE=70
DO=71 WHILE=71
FOR=72 DO=72
SWITCH=73 FOR=73
RETURN=74 SWITCH=74
BREAK=75 RETURN=75
CONTINUE=76 BREAK=76
ASM=77 CONTINUE=77
DEFAULT=78 ASM=78
CASE=79 DEFAULT=79
STRUCT=80 CASE=80
ENUM=81 STRUCT=81
SIZEOF=82 ENUM=82
TYPEID=83 SIZEOF=83
DEFINED=84 TYPEID=84
KICKASM=85 DEFINED=85
RESOURCE=86 KICKASM=86
USES=87 RESOURCE=87
CLOBBERS=88 USES=88
BYTES=89 CLOBBERS=89
CYCLES=90 BYTES=90
LOGIC_NOT=91 CYCLES=91
SIGNEDNESS=92 LOGIC_NOT=92
SIMPLETYPE=93 SIGNEDNESS=93
BOOLEAN=94 SIMPLETYPE=94
KICKASM_BODY=95 BOOLEAN=95
IMPORT=96 KICKASM_BODY=96
INCLUDE=97 IMPORT=97
PRAGMA=98 INCLUDE=98
DEFINE=99 PRAGMA=99
DEFINE_CONTINUE=100 DEFINE=100
UNDEF=101 DEFINE_CONTINUE=101
IFDEF=102 UNDEF=102
IFNDEF=103 IFDEF=103
IFIF=104 IFNDEF=104
ELIF=105 IFIF=105
IFELSE=106 ELIF=106
ENDIF=107 IFELSE=107
NUMBER=108 ENDIF=108
NUMFLOAT=109 NUMBER=109
BINFLOAT=110 NUMFLOAT=110
DECFLOAT=111 BINFLOAT=111
HEXFLOAT=112 DECFLOAT=112
NUMINT=113 HEXFLOAT=113
BININTEGER=114 NUMINT=114
DECINTEGER=115 BININTEGER=115
HEXINTEGER=116 DECINTEGER=116
NAME=117 HEXINTEGER=117
STRING=118 NAME=118
CHAR=119 STRING=119
WS=120 CHAR=120
COMMENT_LINE=121 WS=121
COMMENT_BLOCK=122 COMMENT_LINE=122
ASM_BYTE=123 COMMENT_BLOCK=123
ASM_MNEMONIC=124 ASM_BYTE=124
ASM_IMM=125 ASM_MNEMONIC=125
ASM_COLON=126 ASM_IMM=126
ASM_COMMA=127 ASM_COLON=127
ASM_PAR_BEGIN=128 ASM_COMMA=128
ASM_PAR_END=129 ASM_PAR_BEGIN=129
ASM_BRACKET_BEGIN=130 ASM_PAR_END=130
ASM_BRACKET_END=131 ASM_BRACKET_BEGIN=131
ASM_DOT=132 ASM_BRACKET_END=132
ASM_SHIFT_LEFT=133 ASM_DOT=133
ASM_SHIFT_RIGHT=134 ASM_SHIFT_LEFT=134
ASM_PLUS=135 ASM_SHIFT_RIGHT=135
ASM_MINUS=136 ASM_PLUS=136
ASM_LESS_THAN=137 ASM_MINUS=137
ASM_GREATER_THAN=138 ASM_LESS_THAN=138
ASM_MULTIPLY=139 ASM_GREATER_THAN=139
ASM_DIVIDE=140 ASM_MULTIPLY=140
ASM_CURLY_BEGIN=141 ASM_DIVIDE=141
ASM_CURLY_END=142 ASM_CURLY_BEGIN=142
ASM_NUMBER=143 ASM_CURLY_END=143
ASM_NUMFLOAT=144 ASM_NUMBER=144
ASM_BINFLOAT=145 ASM_NUMFLOAT=145
ASM_DECFLOAT=146 ASM_BINFLOAT=146
ASM_HEXFLOAT=147 ASM_DECFLOAT=147
ASM_NUMINT=148 ASM_HEXFLOAT=148
ASM_BININTEGER=149 ASM_NUMINT=149
ASM_DECINTEGER=150 ASM_BININTEGER=150
ASM_HEXINTEGER=151 ASM_DECINTEGER=151
ASM_CHAR=152 ASM_HEXINTEGER=152
ASM_MULTI_REL=153 ASM_CHAR=153
ASM_MULTI_NAME=154 ASM_MULTI_REL=154
ASM_NAME=155 ASM_MULTI_NAME=155
ASM_WS=156 ASM_NAME=156
ASM_COMMENT_LINE=157 ASM_WS=157
ASM_COMMENT_BLOCK=158 ASM_COMMENT_LINE=158
IMPORT_SYSTEMFILE=159 ASM_COMMENT_BLOCK=159
IMPORT_LOCALFILE=160 IMPORT_SYSTEMFILE=160
IMPORT_WS=161 IMPORT_LOCALFILE=161
IMPORT_COMMENT_LINE=162 IMPORT_WS=162
IMPORT_COMMENT_BLOCK=163 IMPORT_COMMENT_LINE=163
IMPORT_COMMENT_BLOCK=164
';'=8 ';'=8
'..'=11 '..'=11
'...'=12 '...'=12
@ -181,7 +182,7 @@ IMPORT_COMMENT_BLOCK=163
'||'=36 '||'=36
'='=37 '='=37
'typedef'=39 'typedef'=39
'reserve'=40 'zp_reserve'=40
'pc'=41 'pc'=41
'target'=42 'target'=42
'link'=43 'link'=43
@ -200,48 +201,49 @@ IMPORT_COMMENT_BLOCK=163
'static'=56 'static'=56
'interrupt'=57 'interrupt'=57
'register'=58 'register'=58
'__address'=59 '__zp_reserve'=59
'__zp'=60 '__address'=60
'__mem'=61 '__zp'=61
'__ssa'=62 '__mem'=62
'__ma'=63 '__ssa'=63
'__intrinsic'=64 '__ma'=64
'calling'=65 '__intrinsic'=65
'var_model'=67 'calling'=66
'if'=68 'var_model'=68
'else'=69 'if'=69
'while'=70 'else'=70
'do'=71 'while'=71
'for'=72 'do'=72
'switch'=73 'for'=73
'return'=74 'switch'=74
'break'=75 'return'=75
'continue'=76 'break'=76
'asm'=77 'continue'=77
'default'=78 'asm'=78
'case'=79 'default'=79
'struct'=80 'case'=80
'enum'=81 'struct'=81
'sizeof'=82 'enum'=82
'typeid'=83 'sizeof'=83
'defined'=84 'typeid'=84
'kickasm'=85 'defined'=85
'resource'=86 'kickasm'=86
'uses'=87 'resource'=87
'clobbers'=88 'uses'=88
'bytes'=89 'clobbers'=89
'cycles'=90 'bytes'=90
'!'=91 'cycles'=91
'#import'=96 '!'=92
'#include'=97 '#import'=97
'#pragma'=98 '#include'=98
'#define'=99 '#pragma'=99
'#undef'=101 '#define'=100
'#ifdef'=102 '#undef'=102
'#ifndef'=103 '#ifdef'=103
'#if'=104 '#ifndef'=104
'#elif'=105 '#if'=105
'#else'=106 '#elif'=106
'#endif'=107 '#else'=107
'.byte'=123 '#endif'=108
'#'=125 '.byte'=124
'#'=126

View File

@ -151,7 +151,7 @@ globalDirective
| (PRAGMA LINK) PAR_BEGIN STRING PAR_END #globalDirectiveLinkScript | (PRAGMA LINK) PAR_BEGIN STRING PAR_END #globalDirectiveLinkScript
| (PRAGMA EXTENSION) PAR_BEGIN STRING PAR_END #globalDirectiveExtension | (PRAGMA EXTENSION) PAR_BEGIN STRING PAR_END #globalDirectiveExtension
| (PRAGMA EMULATOR) PAR_BEGIN STRING PAR_END #globalDirectiveEmulator | (PRAGMA EMULATOR) PAR_BEGIN STRING PAR_END #globalDirectiveEmulator
| (PRAGMA RESERVE) PAR_BEGIN NUMBER ( COMMA NUMBER )* PAR_END #globalDirectiveReserve | (PRAGMA RESERVE) PAR_BEGIN directiveReserveParam ( COMMA directiveReserveParam )* PAR_END #globalDirectiveReserve
| (PRAGMA PC) PAR_BEGIN NUMBER PAR_END #globalDirectivePc | (PRAGMA PC) PAR_BEGIN NUMBER PAR_END #globalDirectivePc
| (PRAGMA CODESEG) PAR_BEGIN NAME PAR_END #globalDirectiveCodeSeg | (PRAGMA CODESEG) PAR_BEGIN NAME PAR_END #globalDirectiveCodeSeg
| (PRAGMA DATASEG) PAR_BEGIN NAME PAR_END #globalDirectiveDataSeg | (PRAGMA DATASEG) PAR_BEGIN NAME PAR_END #globalDirectiveDataSeg
@ -160,6 +160,10 @@ globalDirective
| (PRAGMA VARMODEL) PAR_BEGIN NAME ( COMMA NAME )* PAR_END #globalDirectiveVarModel | (PRAGMA VARMODEL) PAR_BEGIN NAME ( COMMA NAME )* PAR_END #globalDirectiveVarModel
; ;
directiveReserveParam
: NUMBER (RANGE NUMBER)?
;
directive directive
: CONST #directiveConst : CONST #directiveConst
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign | ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
@ -176,7 +180,7 @@ directive
| INLINE #directiveInline | INLINE #directiveInline
| INTRINSIC #directiveIntrinsic | INTRINSIC #directiveIntrinsic
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt | INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
| RESERVE PAR_BEGIN NUMBER ( COMMA NUMBER )* PAR_END #directiveReserveZp | LOCAL_RESERVE PAR_BEGIN directiveReserveParam ( COMMA directiveReserveParam )* PAR_END #directiveReserveZp
| CALLINGCONVENTION #directiveCallingConvention | CALLINGCONVENTION #directiveCallingConvention
; ;
@ -210,7 +214,7 @@ switchCase:
forLoop forLoop
: forClassicInit ';' commaExpr ';' commaExpr? #forClassic : forClassicInit ';' commaExpr ';' commaExpr? #forClassic
| (declType declPointer*)? NAME COLON expr '..' expr #forRange | (declType declPointer*)? NAME COLON expr RANGE expr #forRange
; ;
forClassicInit forClassicInit

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -56,111 +56,112 @@ VOLATILE=55
STATIC=56 STATIC=56
INTERRUPT=57 INTERRUPT=57
REGISTER=58 REGISTER=58
ADDRESS=59 LOCAL_RESERVE=59
ADDRESS_ZEROPAGE=60 ADDRESS=60
ADDRESS_MAINMEM=61 ADDRESS_ZEROPAGE=61
FORM_SSA=62 ADDRESS_MAINMEM=62
FORM_MA=63 FORM_SSA=63
INTRINSIC=64 FORM_MA=64
CALLING=65 INTRINSIC=65
CALLINGCONVENTION=66 CALLING=66
VARMODEL=67 CALLINGCONVENTION=67
IF=68 VARMODEL=68
ELSE=69 IF=69
WHILE=70 ELSE=70
DO=71 WHILE=71
FOR=72 DO=72
SWITCH=73 FOR=73
RETURN=74 SWITCH=74
BREAK=75 RETURN=75
CONTINUE=76 BREAK=76
ASM=77 CONTINUE=77
DEFAULT=78 ASM=78
CASE=79 DEFAULT=79
STRUCT=80 CASE=80
ENUM=81 STRUCT=81
SIZEOF=82 ENUM=82
TYPEID=83 SIZEOF=83
DEFINED=84 TYPEID=84
KICKASM=85 DEFINED=85
RESOURCE=86 KICKASM=86
USES=87 RESOURCE=87
CLOBBERS=88 USES=88
BYTES=89 CLOBBERS=89
CYCLES=90 BYTES=90
LOGIC_NOT=91 CYCLES=91
SIGNEDNESS=92 LOGIC_NOT=92
SIMPLETYPE=93 SIGNEDNESS=93
BOOLEAN=94 SIMPLETYPE=94
KICKASM_BODY=95 BOOLEAN=95
IMPORT=96 KICKASM_BODY=96
INCLUDE=97 IMPORT=97
PRAGMA=98 INCLUDE=98
DEFINE=99 PRAGMA=99
DEFINE_CONTINUE=100 DEFINE=100
UNDEF=101 DEFINE_CONTINUE=101
IFDEF=102 UNDEF=102
IFNDEF=103 IFDEF=103
IFIF=104 IFNDEF=104
ELIF=105 IFIF=105
IFELSE=106 ELIF=106
ENDIF=107 IFELSE=107
NUMBER=108 ENDIF=108
NUMFLOAT=109 NUMBER=109
BINFLOAT=110 NUMFLOAT=110
DECFLOAT=111 BINFLOAT=111
HEXFLOAT=112 DECFLOAT=112
NUMINT=113 HEXFLOAT=113
BININTEGER=114 NUMINT=114
DECINTEGER=115 BININTEGER=115
HEXINTEGER=116 DECINTEGER=116
NAME=117 HEXINTEGER=117
STRING=118 NAME=118
CHAR=119 STRING=119
WS=120 CHAR=120
COMMENT_LINE=121 WS=121
COMMENT_BLOCK=122 COMMENT_LINE=122
ASM_BYTE=123 COMMENT_BLOCK=123
ASM_MNEMONIC=124 ASM_BYTE=124
ASM_IMM=125 ASM_MNEMONIC=125
ASM_COLON=126 ASM_IMM=126
ASM_COMMA=127 ASM_COLON=127
ASM_PAR_BEGIN=128 ASM_COMMA=128
ASM_PAR_END=129 ASM_PAR_BEGIN=129
ASM_BRACKET_BEGIN=130 ASM_PAR_END=130
ASM_BRACKET_END=131 ASM_BRACKET_BEGIN=131
ASM_DOT=132 ASM_BRACKET_END=132
ASM_SHIFT_LEFT=133 ASM_DOT=133
ASM_SHIFT_RIGHT=134 ASM_SHIFT_LEFT=134
ASM_PLUS=135 ASM_SHIFT_RIGHT=135
ASM_MINUS=136 ASM_PLUS=136
ASM_LESS_THAN=137 ASM_MINUS=137
ASM_GREATER_THAN=138 ASM_LESS_THAN=138
ASM_MULTIPLY=139 ASM_GREATER_THAN=139
ASM_DIVIDE=140 ASM_MULTIPLY=140
ASM_CURLY_BEGIN=141 ASM_DIVIDE=141
ASM_CURLY_END=142 ASM_CURLY_BEGIN=142
ASM_NUMBER=143 ASM_CURLY_END=143
ASM_NUMFLOAT=144 ASM_NUMBER=144
ASM_BINFLOAT=145 ASM_NUMFLOAT=145
ASM_DECFLOAT=146 ASM_BINFLOAT=146
ASM_HEXFLOAT=147 ASM_DECFLOAT=147
ASM_NUMINT=148 ASM_HEXFLOAT=148
ASM_BININTEGER=149 ASM_NUMINT=149
ASM_DECINTEGER=150 ASM_BININTEGER=150
ASM_HEXINTEGER=151 ASM_DECINTEGER=151
ASM_CHAR=152 ASM_HEXINTEGER=152
ASM_MULTI_REL=153 ASM_CHAR=153
ASM_MULTI_NAME=154 ASM_MULTI_REL=154
ASM_NAME=155 ASM_MULTI_NAME=155
ASM_WS=156 ASM_NAME=156
ASM_COMMENT_LINE=157 ASM_WS=157
ASM_COMMENT_BLOCK=158 ASM_COMMENT_LINE=158
IMPORT_SYSTEMFILE=159 ASM_COMMENT_BLOCK=159
IMPORT_LOCALFILE=160 IMPORT_SYSTEMFILE=160
IMPORT_WS=161 IMPORT_LOCALFILE=161
IMPORT_COMMENT_LINE=162 IMPORT_WS=162
IMPORT_COMMENT_BLOCK=163 IMPORT_COMMENT_LINE=163
IMPORT_COMMENT_BLOCK=164
';'=8 ';'=8
'..'=11 '..'=11
'...'=12 '...'=12
@ -181,7 +182,7 @@ IMPORT_COMMENT_BLOCK=163
'||'=36 '||'=36
'='=37 '='=37
'typedef'=39 'typedef'=39
'reserve'=40 'zp_reserve'=40
'pc'=41 'pc'=41
'target'=42 'target'=42
'link'=43 'link'=43
@ -200,48 +201,49 @@ IMPORT_COMMENT_BLOCK=163
'static'=56 'static'=56
'interrupt'=57 'interrupt'=57
'register'=58 'register'=58
'__address'=59 '__zp_reserve'=59
'__zp'=60 '__address'=60
'__mem'=61 '__zp'=61
'__ssa'=62 '__mem'=62
'__ma'=63 '__ssa'=63
'__intrinsic'=64 '__ma'=64
'calling'=65 '__intrinsic'=65
'var_model'=67 'calling'=66
'if'=68 'var_model'=68
'else'=69 'if'=69
'while'=70 'else'=70
'do'=71 'while'=71
'for'=72 'do'=72
'switch'=73 'for'=73
'return'=74 'switch'=74
'break'=75 'return'=75
'continue'=76 'break'=76
'asm'=77 'continue'=77
'default'=78 'asm'=78
'case'=79 'default'=79
'struct'=80 'case'=80
'enum'=81 'struct'=81
'sizeof'=82 'enum'=82
'typeid'=83 'sizeof'=83
'defined'=84 'typeid'=84
'kickasm'=85 'defined'=85
'resource'=86 'kickasm'=86
'uses'=87 'resource'=87
'clobbers'=88 'uses'=88
'bytes'=89 'clobbers'=89
'cycles'=90 'bytes'=90
'!'=91 'cycles'=91
'#import'=96 '!'=92
'#include'=97 '#import'=97
'#pragma'=98 '#include'=98
'#define'=99 '#pragma'=99
'#undef'=101 '#define'=100
'#ifdef'=102 '#undef'=102
'#ifndef'=103 '#ifdef'=103
'#if'=104 '#ifndef'=104
'#elif'=105 '#if'=105
'#else'=106 '#elif'=106
'#endif'=107 '#else'=107
'.byte'=123 '#endif'=108
'#'=125 '.byte'=124
'#'=126

View File

@ -661,6 +661,18 @@ public class KickCParserBaseListener implements KickCParserListener {
* <p>The default implementation does nothing.</p> * <p>The default implementation does nothing.</p>
*/ */
@Override public void exitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { } @Override public void exitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx) { }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

View File

@ -391,6 +391,13 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
* {@link #visitChildren} on {@code ctx}.</p> * {@link #visitChildren} on {@code ctx}.</p>
*/ */
@Override public T visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { return visitChildren(ctx); } @Override public T visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx) { return visitChildren(ctx); }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

View File

@ -615,6 +615,16 @@ public interface KickCParserListener extends ParseTreeListener {
* @param ctx the parse tree * @param ctx the parse tree
*/ */
void exitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx); void exitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#directiveReserveParam}.
* @param ctx the parse tree
*/
void enterDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx);
/**
* Exit a parse tree produced by {@link KickCParser#directiveReserveParam}.
* @param ctx the parse tree
*/
void exitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx);
/** /**
* Enter a parse tree produced by the {@code directiveConst} * Enter a parse tree produced by the {@code directiveConst}
* labeled alternative in {@link KickCParser#directive}. * labeled alternative in {@link KickCParser#directive}.

View File

@ -369,6 +369,12 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result * @return the visitor result
*/ */
T visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx); T visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#directiveReserveParam}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx);
/** /**
* Visit a parse tree produced by the {@code directiveConst} * Visit a parse tree produced by the {@code directiveConst}
* labeled alternative in {@link KickCParser#directive}. * labeled alternative in {@link KickCParser#directive}.

View File

@ -155,15 +155,40 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override @Override
public Object visitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) { public Object visitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) {
List<Integer> reservedZps = new ArrayList<>(); final List<KickCParser.DirectiveReserveParamContext> reserveParams = ctx.directiveReserveParam();
for(TerminalNode reservedNum : ctx.NUMBER()) { List<Integer> reservedZps = getReservedZps(reserveParams);
Number reservedZp = NumberParser.parseLiteral(reservedNum.getText());
reservedZps.add(reservedZp.intValue());
}
program.addReservedZps(reservedZps); program.addReservedZps(reservedZps);
return null; return null;
} }
/**
* Find the list of all reserved ZP-addresses from a list of reserve parameters (potentially including ranges)
* @param reserveParams The params
* @return The list of reserved zeropage addresses
*/
private List<Integer> getReservedZps(List<KickCParser.DirectiveReserveParamContext> reserveParams) {
List<Integer> reservedZps = new ArrayList<>();
for(KickCParser.DirectiveReserveParamContext reserveCtx : reserveParams) {
final TerminalNode rangeStart = reserveCtx.NUMBER(0);
final TerminalNode rangeEnd = reserveCtx.NUMBER(1);
if(rangeEnd==null) {
// Only a single reserved address
Number reservedZp = NumberParser.parseLiteral(rangeStart.getText());
reservedZps.add(reservedZp.intValue());
} else {
// A range of reserved addresses
Number startZp = NumberParser.parseLiteral(rangeStart.getText());
Number endZp = NumberParser.parseLiteral(rangeEnd.getText());
int zp = startZp.intValue();
while(zp<=endZp.intValue()) {
reservedZps.add(zp);
zp++;
}
}
}
return reservedZps;
}
@Override @Override
public Object visitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) { public Object visitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) {
try { try {
@ -1155,11 +1180,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override @Override
public Directive visitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) { public Directive visitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) {
List<Integer> reservedZps = new ArrayList<>(); final List<KickCParser.DirectiveReserveParamContext> reserveParams = ctx.directiveReserveParam();
for(TerminalNode reservedNum : ctx.NUMBER()) { final List<Integer> reservedZps = getReservedZps(reserveParams);
int reservedZp = NumberParser.parseLiteral(reservedNum.getText()).intValue();
reservedZps.add(reservedZp);
}
return new Directive.ReserveZp(reservedZps); return new Directive.ReserveZp(reservedZps);
} }

View File

@ -2307,11 +2307,21 @@ public class TestPrograms {
compileAndCompare("strip.c"); compileAndCompare("strip.c");
} }
@Test
public void testReserveZpGlobalRange() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-global-range.c");
}
@Test @Test
public void testReserveZpGlobal() throws IOException, URISyntaxException { public void testReserveZpGlobal() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-global.c"); compileAndCompare("reserve-zp-global.c");
} }
@Test
public void testReserveZpProcedure4() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-procedure-4.c");
}
@Test @Test
public void testReserveZpProcedure3() throws IOException, URISyntaxException { public void testReserveZpProcedure3() throws IOException, URISyntaxException {
compileAndCompare("reserve-zp-procedure-3.c"); compileAndCompare("reserve-zp-procedure-3.c");

View File

@ -7,7 +7,7 @@
// Data // Data
#pragma data_seg(Data) #pragma data_seg(Data)
const char SINTABLE_160[0x100] = kickasm {{ const char SINTABLE_160[0x100] = kickasm {{
.fill $100, 5+round(74.5+74.5*sin(2*PI*i/256)) .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256))
}}; }};
char SPRITE_C[] = { char SPRITE_C[] = {
@ -47,7 +47,6 @@ char SPRITE_C[] = {
0 0
}; };
// Variables // Variables
#pragma data_seg(Vars) #pragma data_seg(Vars)
// Counts frames // Counts frames
@ -66,12 +65,8 @@ void main() {
TIA->COLUP0 = 0xf0; TIA->COLUP0 = 0xf0;
// - Graphics // - Graphics
TIA->GRP0 = 0xaf; TIA->GRP0 = 0xaf;
// - Size
// Player 1 TIA->NUSIZ0 = 0x05;
// - Color
//TIA->COLUP1 = 0xf0;
// - Graphics
//TIA->GRP1 = 0xf5;
while(1) { while(1) {

View File

@ -173,7 +173,7 @@ void gen_chargen_sprite(char ch, char* sprite) {
} }
// Reserve zeropage addresses used by the BASIC FP operations // Reserve zeropage addresses used by the BASIC FP operations
#pragma reserve(0x07, 0x0d, 0x0e, 0x12) #pragma zp_reserve(0x07, 0x0d, 0x0e, 0x12)
// Generate a sinus table using BASIC floats // Generate a sinus table using BASIC floats
// - sintab is a pointer to the table to fill // - sintab is a pointer to the table to fill

View File

@ -1,4 +1,4 @@
#pragma reserve(0x16) #pragma zp_reserve(0x16)
#pragma encoding(petscii_mixed) #pragma encoding(petscii_mixed)
char strTemp[] = "v=X"; char strTemp[] = "v=X";
int main(void){ int main(void){

View File

@ -0,0 +1,15 @@
// Demonstrates global directive reserving a range of addresses on zeropage
#pragma zp_reserve(0x00..0x7f)
void main() {
byte* const SCREEN = $400;
for( volatile byte i : 0..2) {
SCREEN[i] = sub1(i);
}
}
__zp_reserve(0x80) byte sub1(byte i) {
return i+i;
}

View File

@ -1,6 +1,6 @@
// Demonstrates global directive reserving addresses on zeropage // Demonstrates global directive reserving addresses on zeropage
#pragma reserve(2,5) #pragma zp_reserve(2,5)
void main() { void main() {
byte* const SCREEN = $400; byte* const SCREEN = $400;
@ -9,7 +9,7 @@ void main() {
} }
} }
reserve(3) byte sub1(byte i) { __zp_reserve(3) byte sub1(byte i) {
return i+i; return i+i;
} }

View File

@ -7,6 +7,6 @@ void main() {
} }
} }
reserve(2, 3, 4) byte sub1(byte i) { __zp_reserve(2, 3, 4) byte sub1(byte i) {
return i+i; return i+i;
} }

View File

@ -8,10 +8,10 @@ void main() {
} }
} }
reserve(2, 3, 4) byte sub1(byte i) { __zp_reserve(2, 3, 4) byte sub1(byte i) {
return i+i; return i+i;
} }
reserve(5, 6, 7) byte sub2(byte i) { __zp_reserve(5, 6, 7) byte sub2(byte i) {
return i+i+i; return i+i+i;
} }

View File

@ -7,10 +7,10 @@ void main() {
} }
} }
reserve(2, 3, 4) byte sub1(byte i) { __zp_reserve(2, 3, 4) byte sub1(byte i) {
return i+i; return i+i;
} }
reserve(5, 6, 7) byte sub2(byte i) { __zp_reserve(5, 6, 7) byte sub2(byte i) {
return i+i+i; return i+i+i;
} }

View File

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

View File

@ -7,7 +7,7 @@
#include <time.h> #include <time.h>
#include <print.h> #include <print.h>
#pragma reserve(08) #pragma zp_reserve(08)
byte* const CHARSET = 0x2000; byte* const CHARSET = 0x2000;
byte* const SCREEN = 0x2800; byte* const SCREEN = 0x2800;

View File

@ -1,7 +1,7 @@
// Tests warning when running out of zeropage-addresses for variables // Tests warning when running out of zeropage-addresses for variables
// Start by reserving most of zeropage (254 bytes) // Start by reserving most of zeropage (254 bytes)
#pragma reserve(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,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,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254) #pragma zp_reserve(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,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,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254)
// And then allocate a 2-byte-variable // And then allocate a 2-byte-variable
void main() { void main() {

View File

@ -16,6 +16,7 @@
.const CYCLES_PER_SCANLINE = $4c .const CYCLES_PER_SCANLINE = $4c
.const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = 6 .const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = 6
.const OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 = $1b .const OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 = $1b
.const OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0 = 4
.const OFFSET_STRUCT_MOS6532_RIOT_TIM64T = $16 .const OFFSET_STRUCT_MOS6532_RIOT_TIM64T = $16
.const OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = 2 .const OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = 2
.const OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = $2a .const OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = $2a
@ -45,15 +46,14 @@ main: {
// - Graphics // - Graphics
lda #$af lda #$af
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0
// TIA->NUSIZ0 = 0x05
// - Size
lda #5
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0
lda #$39 lda #$39
sta idx2 sta idx2
lda #0 lda #0
sta idx sta idx
// Player 1
// - Color
//TIA->COLUP1 = 0xf0;
// - Graphics
//TIA->GRP1 = 0xf5;
__b2: __b2:
// TIA->VSYNC = 2 // TIA->VSYNC = 2
// Vertical Sync // Vertical Sync
@ -198,7 +198,7 @@ main: {
} }
.segment Data .segment Data
SINTABLE_160: SINTABLE_160:
.fill $100, 5+round(74.5+74.5*sin(2*PI*i/256)) .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256))
SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0 SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0
.segment Vars .segment Vars

View File

@ -13,73 +13,74 @@ main: scope:[main] from @1
asm { cld } asm { cld }
[5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0) ← (byte) $f0 [5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0) ← (byte) $f0
[6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) $af [6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) $af
[7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0) ← (byte) 5
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@13 main::@1: scope:[main] from main main::@13
[7] (byte) idx2#2 ← phi( main/(byte) $39 main::@13/(byte) idx2#1 ) [8] (byte) idx2#2 ← phi( main/(byte) $39 main::@13/(byte) idx2#1 )
[7] (byte) idx#2 ← phi( main/(byte) 0 main::@13/(byte) idx#1 ) [8] (byte) idx#2 ← phi( main/(byte) 0 main::@13/(byte) idx#1 )
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2: scope:[main] from main::@1
[8] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2 [9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2
[9] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40
[10] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0 [13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[14] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0
asm { ldap0_xpos staTIA_WSYNC sec !: sbc#$f bcs!- eor#7 asl asl asl asl staTIA_HMP0 staTIA_RESP0 } asm { ldap0_xpos staTIA_WSYNC sec !: sbc#$f bcs!- eor#7 asl asl asl asl staTIA_HMP0 staTIA_RESP0 }
[15] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2)
[16] (byte) idx#1 ← ++ (byte) idx#2 [17] (byte) idx#1 ← ++ (byte) idx#2
[17] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2)
[18] (byte) idx2#1 ← ++ (byte) idx2#2 [19] (byte) idx2#1 ← ++ (byte) idx2#2
[19] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0 [21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0
to:main::@3 to:main::@3
main::@3: scope:[main] from main::@2 main::@4 main::@3: scope:[main] from main::@2 main::@4
[21] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 [22] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4
to:main::@5 to:main::@5
main::@5: scope:[main] from main::@3 main::@5: scope:[main] from main::@3
[22] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0 [23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0
[23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [24] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
to:main::@6 to:main::@6
main::@6: scope:[main] from main::@10 main::@5 main::@6: scope:[main] from main::@10 main::@5
[24] (byte) main::p0_idx#4 ← phi( main::@10/(byte) main::p0_idx#8 main::@5/(byte) 0 ) [25] (byte) main::p0_idx#4 ← phi( main::@10/(byte) main::p0_idx#8 main::@5/(byte) 0 )
[24] (byte) main::i#2 ← phi( main::@10/(byte) main::i#1 main::@5/(byte) 1 ) [25] (byte) main::i#2 ← phi( main::@10/(byte) main::i#1 main::@5/(byte) 1 )
[25] if((byte) main::i#2<(byte) $c0) goto main::@7 [26] if((byte) main::i#2<(byte) $c0) goto main::@7
to:main::@8 to:main::@8
main::@8: scope:[main] from main::@6 main::@8: scope:[main] from main::@6
[26] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2 [28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2
[28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
[29] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [30] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40
to:main::@13 to:main::@13
main::@13: scope:[main] from main::@14 main::@8 main::@13: scope:[main] from main::@14 main::@8
[30] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14 [31] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14
to:main::@1 to:main::@1
main::@14: scope:[main] from main::@13 main::@14: scope:[main] from main::@13
[31] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
to:main::@13 to:main::@13
main::@7: scope:[main] from main::@6 main::@7: scope:[main] from main::@6
[32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::i#2 [34] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::i#2
[34] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9 [35] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9
to:main::@11 to:main::@11
main::@11: scope:[main] from main::@7 main::@11: scope:[main] from main::@7
[35] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15
to:main::@10 to:main::@10
main::@15: scope:[main] from main::@11 main::@15: scope:[main] from main::@11
[36] phi() [37] phi()
to:main::@10 to:main::@10
main::@10: scope:[main] from main::@11 main::@12 main::@15 main::@9 main::@10: scope:[main] from main::@11 main::@12 main::@15 main::@9
[37] (byte) main::p0_idx#8 ← phi( main::@9/(byte) 0 main::@15/(byte) main::p0_idx#4 main::@11/(byte) 1 main::@12/(byte) main::p0_idx#3 ) [38] (byte) main::p0_idx#8 ← phi( main::@9/(byte) 0 main::@15/(byte) main::p0_idx#4 main::@11/(byte) 1 main::@12/(byte) main::p0_idx#3 )
[38] (byte) main::i#1 ← ++ (byte) main::i#2 [39] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@6 to:main::@6
main::@9: scope:[main] from main::@7 main::@9: scope:[main] from main::@7
[39] (byte) main::gfx#0 ← *((const byte*) SPRITE_C + (byte) main::p0_idx#4) [40] (byte) main::gfx#0 ← *((const byte*) SPRITE_C + (byte) main::p0_idx#4)
[40] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) main::gfx#0 [41] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) main::gfx#0
[41] if((byte) main::gfx#0==(byte) 0) goto main::@10 [42] if((byte) main::gfx#0==(byte) 0) goto main::@10
to:main::@12 to:main::@12
main::@12: scope:[main] from main::@9 main::@12: scope:[main] from main::@9
[42] (byte) main::p0_idx#3 ← ++ (byte) main::p0_idx#4 [43] (byte) main::p0_idx#3 ← ++ (byte) main::p0_idx#4
to:main::@10 to:main::@10
main::@4: scope:[main] from main::@3 main::@4: scope:[main] from main::@3
[43] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [44] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
to:main::@3 to:main::@3

File diff suppressed because it is too large Load Diff

View File

@ -75,12 +75,13 @@
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = (byte) 6 (const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = (byte) 6
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 = (byte) $1b (const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 = (byte) $1b
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = (byte) $2a (const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = (byte) $2a
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0 = (byte) 4
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK = (byte) 1 (const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK = (byte) 1
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = (byte) 2 (const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = (byte) 2
(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM = (byte) 4 (const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM = (byte) 4
(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T = (byte) $16 (const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T = (byte) $16
(const nomodify struct MOS6532_RIOT*) RIOT = (struct MOS6532_RIOT*) 640 (const nomodify struct MOS6532_RIOT*) RIOT = (struct MOS6532_RIOT*) 640
(const to_nomodify byte*) SINTABLE_160[(number) $100] = kickasm {{ .fill $100, 5+round(74.5+74.5*sin(2*PI*i/256)) (const to_nomodify byte*) SINTABLE_160[(number) $100] = kickasm {{ .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256))
}} }}
(const byte*) SPRITE_C[] = { (byte) 0, (byte) $18, (byte) $18, (byte) $18, (byte) $18, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $66, (byte) $66, (byte) $66, (byte) $66, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $66, (byte) $66, (byte) $66, (byte) $66, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $18, (byte) $18, (byte) $18, (byte) $18, (byte) 0 } (const byte*) SPRITE_C[] = { (byte) 0, (byte) $18, (byte) $18, (byte) $18, (byte) $18, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $66, (byte) $66, (byte) $66, (byte) $66, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $66, (byte) $66, (byte) $66, (byte) $66, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $18, (byte) $18, (byte) $18, (byte) $18, (byte) 0 }
(const nomodify struct ATARI_TIA_WRITE*) TIA = (struct ATARI_TIA_WRITE*) 0 (const nomodify struct ATARI_TIA_WRITE*) TIA = (struct ATARI_TIA_WRITE*) 0
@ -118,7 +119,7 @@
(byte) main::p0_idx#3 reg byte y 2002.0 (byte) main::p0_idx#3 reg byte y 2002.0
(byte) main::p0_idx#4 reg byte y 500.5 (byte) main::p0_idx#4 reg byte y 500.5
(byte) main::p0_idx#8 reg byte y 1501.5 (byte) main::p0_idx#8 reg byte y 1501.5
(byte) p0_xpos loadstore mem[1] 2.4634146341463414 = (byte) 0 (byte) p0_xpos loadstore mem[1] 2.4047619047619047 = (byte) 0
(byte) p0_ypos (byte) p0_ypos
(byte) p0_ypos#1 p0_ypos mem[1] 52.476190476190474 (byte) p0_ypos#1 p0_ypos mem[1] 52.476190476190474

View File

@ -0,0 +1,32 @@
// Demonstrates global directive reserving a range of addresses on zeropage
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
.label SCREEN = $400
.label i = $81
// for( volatile byte i : 0..2)
lda #0
sta.z i
__b1:
// sub1(i)
lda.z i
jsr sub1
// SCREEN[i] = sub1(i)
ldy.z i
sta SCREEN,y
// for( volatile byte i : 0..2)
inc.z i
lda #3
cmp.z i
bne __b1
// }
rts
}
// sub1(byte register(A) i)
sub1: {
// i+i
asl
// }
rts
}

View File

@ -0,0 +1,36 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] (volatile byte) main::i ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) sub1::i#0 ← (volatile byte) main::i
[6] call sub1
[7] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[8] (byte~) main::$0 ← (byte) sub1::return#0
[9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0
[10] (volatile byte) main::i ← ++ (volatile byte) main::i
[11] if((volatile byte) main::i!=(byte) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[12] return
to:@return
(byte()) sub1((byte) sub1::i)
sub1: scope:[sub1] from main::@1
[13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[14] return
to:@return

View File

@ -0,0 +1,453 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) main()
main: scope:[main] from @1
(volatile byte) main::i ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
(byte) sub1::i#0 ← (volatile byte) main::i
call sub1
(byte) sub1::return#0 ← (byte) sub1::return#2
to:main::@2
main::@2: scope:[main] from main::@1
(byte) sub1::return#3 ← phi( main::@1/(byte) sub1::return#0 )
(byte~) main::$0 ← (byte) sub1::return#3
*((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0
(volatile byte) main::i ← (volatile byte) main::i + rangenext(0,2)
(bool~) main::$1 ← (volatile byte) main::i != rangelast(0,2)
if((bool~) main::$1) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
(byte()) sub1((byte) sub1::i)
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
@1: scope:[] from @begin
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0
(bool~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(const nomodify byte*) main::SCREEN = (byte*)(number) $400
(volatile byte) main::i loadstore
(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
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Alias sub1::return#0 = sub1::return#3
Alias sub1::return#1 = sub1::$0 sub1::return#4 sub1::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) sub1::i#1 (byte) sub1::i#0
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) main::$1 [8] if((volatile byte) main::i!=rangelast(0,2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Resolved ranged next value [6] main::i ← ++ main::i to ++
Resolved ranged comparison value [8] if(main::i!=rangelast(0,2)) goto main::@1 to (number) 3
Adding number conversion cast (unumber) 3 in if((volatile byte) main::i!=(number) 3) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 3
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Calls in [main] to sub1:7
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @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()
(void()) main()
main: scope:[main] from @1
[4] (volatile byte) main::i ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) sub1::i#0 ← (volatile byte) main::i
[6] call sub1
[7] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[8] (byte~) main::$0 ← (byte) sub1::return#0
[9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0
[10] (volatile byte) main::i ← ++ (volatile byte) main::i
[11] if((volatile byte) main::i!=(byte) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[12] return
to:@return
(byte()) sub1((byte) sub1::i)
sub1: scope:[sub1] from main::@1
[13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[14] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte~) main::$0 202.0
(volatile byte) main::i loadstore 64.5
(byte()) sub1((byte) sub1::i)
(byte) sub1::i
(byte) sub1::i#0 2103.0
(byte) sub1::return
(byte) sub1::return#0 202.0
(byte) sub1::return#1 367.33333333333337
Initial phi equivalence classes
Added variable main::i to live range equivalence class [ main::i ]
Added variable sub1::i#0 to live range equivalence class [ sub1::i#0 ]
Added variable sub1::return#0 to live range equivalence class [ sub1::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable sub1::return#1 to live range equivalence class [ sub1::return#1 ]
Complete equivalence classes
[ main::i ]
[ sub1::i#0 ]
[ sub1::return#0 ]
[ main::$0 ]
[ sub1::return#1 ]
Allocated zp[1]:129 [ main::i ]
Allocated zp[1]:130 [ sub1::i#0 ]
Allocated zp[1]:131 [ sub1::return#0 ]
Allocated zp[1]:132 [ main::$0 ]
Allocated zp[1]:133 [ sub1::return#1 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Demonstrates global directive reserving a range of addresses on zeropage
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label SCREEN = $400
.label i = $81
.label __0 = $84
// [4] (volatile byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
jmp __b1
// main::@1
__b1:
// [5] (byte) sub1::i#0 ← (volatile byte) main::i -- vbuz1=vbuz2
lda.z i
sta.z sub1.i
// [6] call sub1
jsr sub1
// [7] (byte) sub1::return#0 ← (byte) sub1::return#1 -- vbuz1=vbuz2
lda.z sub1.return_1
sta.z sub1.return
jmp __b2
// main::@2
__b2:
// [8] (byte~) main::$0 ← (byte) sub1::return#0 -- vbuz1=vbuz2
lda.z sub1.return
sta.z __0
// [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2
lda.z __0
ldy.z i
sta SCREEN,y
// [10] (volatile byte) main::i ← ++ (volatile byte) main::i -- vbuz1=_inc_vbuz1
inc.z i
// [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp.z i
bne __b1
jmp __breturn
// main::@return
__breturn:
// [12] return
rts
}
// sub1
// sub1(byte zp($82) i)
sub1: {
.label i = $82
.label return = $83
.label return_1 = $85
// [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda.z i
asl
sta.z return_1
jmp __breturn
// sub1::@return
__breturn:
// [14] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (volatile byte) main::i ← (byte) 0 [ main::i ] ( main:2 [ main::i ] { } ) always clobbers reg byte a
Statement [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 [ main::i ] ( main:2 [ main::i ] { } ) always clobbers reg byte y
Statement [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 [ main::i ] ( main:2 [ main::i ] { } ) always clobbers reg byte a
Statement [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:6 [ main::i sub1::return#1 ] { { sub1::i#0 = main::i } { sub1::return#0 = sub1::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:129 [ main::i ] : zp[1]:129 ,
Potential registers zp[1]:130 [ sub1::i#0 ] : zp[1]:130 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:131 [ sub1::return#0 ] : zp[1]:131 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:132 [ main::$0 ] : zp[1]:132 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:133 [ sub1::return#1 ] : zp[1]:133 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [sub1] 2,103: zp[1]:130 [ sub1::i#0 ] 367.33: zp[1]:133 [ sub1::return#1 ] 202: zp[1]:131 [ sub1::return#0 ]
Uplift Scope [main] 202: zp[1]:132 [ main::$0 ] 64.5: zp[1]:129 [ main::i ]
Uplift Scope []
Uplifting [sub1] best 452 combination reg byte a [ sub1::i#0 ] reg byte a [ sub1::return#1 ] reg byte a [ sub1::return#0 ]
Uplifting [main] best 392 combination reg byte a [ main::$0 ] zp[1]:129 [ main::i ]
Uplifting [] best 392 combination
Attempting to uplift remaining variables inzp[1]:129 [ main::i ]
Uplifting [main] best 392 combination zp[1]:129 [ main::i ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Demonstrates global directive reserving a range of addresses on zeropage
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label SCREEN = $400
.label i = $81
// [4] (volatile byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
jmp __b1
// main::@1
__b1:
// [5] (byte) sub1::i#0 ← (volatile byte) main::i -- vbuaa=vbuz1
lda.z i
// [6] call sub1
jsr sub1
// [7] (byte) sub1::return#0 ← (byte) sub1::return#1
jmp __b2
// main::@2
__b2:
// [8] (byte~) main::$0 ← (byte) sub1::return#0
// [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy.z i
sta SCREEN,y
// [10] (volatile byte) main::i ← ++ (volatile byte) main::i -- vbuz1=_inc_vbuz1
inc.z i
// [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp.z i
bne __b1
jmp __breturn
// main::@return
__breturn:
// [12] return
rts
}
// sub1
// sub1(byte register(A) i)
sub1: {
// [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
jmp __breturn
// sub1::@return
__breturn:
// [14] return
rts
}
// File Data
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
Removing instruction __b1_from___bbegin:
Removing instruction __b1:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bbegin:
Removing instruction __bend:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 202.0
(label) main::@1
(label) main::@2
(label) main::@return
(const nomodify byte*) main::SCREEN = (byte*) 1024
(volatile byte) main::i loadstore zp[1]:129 64.5
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 2103.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 202.0
(byte) sub1::return#1 reg byte a 367.33333333333337
zp[1]:129 [ main::i ]
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
// File Comments
// Demonstrates global directive reserving a range of addresses on zeropage
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label SCREEN = $400
.label i = $81
// for( volatile byte i : 0..2)
// [4] (volatile byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
// main::@1
__b1:
// sub1(i)
// [5] (byte) sub1::i#0 ← (volatile byte) main::i -- vbuaa=vbuz1
lda.z i
// [6] call sub1
jsr sub1
// [7] (byte) sub1::return#0 ← (byte) sub1::return#1
// main::@2
// [8] (byte~) main::$0 ← (byte) sub1::return#0
// SCREEN[i] = sub1(i)
// [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy.z i
sta SCREEN,y
// for( volatile byte i : 0..2)
// [10] (volatile byte) main::i ← ++ (volatile byte) main::i -- vbuz1=_inc_vbuz1
inc.z i
// [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp.z i
bne __b1
// main::@return
// }
// [12] return
rts
}
// sub1
// sub1(byte register(A) i)
sub1: {
// i+i
// [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
// sub1::@return
// }
// [14] return
rts
}
// File Data

View File

@ -0,0 +1,23 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 202.0
(label) main::@1
(label) main::@2
(label) main::@return
(const nomodify byte*) main::SCREEN = (byte*) 1024
(volatile byte) main::i loadstore zp[1]:129 64.5
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 2103.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 202.0
(byte) sub1::return#1 reg byte a 367.33333333333337
zp[1]:129 [ main::i ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]

View File

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

View File

@ -0,0 +1,36 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] (volatile byte) main::i ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) sub1::i#0 ← (volatile byte) main::i
[6] call sub1
[7] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[8] (byte~) main::$0 ← (byte) sub1::return#0
[9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0
[10] (volatile byte) main::i ← ++ (volatile byte) main::i
[11] if((volatile byte) main::i!=(byte) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[12] return
to:@return
(byte()) sub1((byte) sub1::i)
sub1: scope:[sub1] from main::@1
[13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[14] return
to:@return

View File

@ -0,0 +1,453 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) main()
main: scope:[main] from @1
(volatile byte) main::i ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
(byte) sub1::i#0 ← (volatile byte) main::i
call sub1
(byte) sub1::return#0 ← (byte) sub1::return#2
to:main::@2
main::@2: scope:[main] from main::@1
(byte) sub1::return#3 ← phi( main::@1/(byte) sub1::return#0 )
(byte~) main::$0 ← (byte) sub1::return#3
*((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0
(volatile byte) main::i ← (volatile byte) main::i + rangenext(0,2)
(bool~) main::$1 ← (volatile byte) main::i != rangelast(0,2)
if((bool~) main::$1) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
(byte()) sub1((byte) sub1::i)
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
@1: scope:[] from @begin
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0
(bool~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(const nomodify byte*) main::SCREEN = (byte*)(number) $400
(volatile byte) main::i loadstore
(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
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Alias sub1::return#0 = sub1::return#3
Alias sub1::return#1 = sub1::$0 sub1::return#4 sub1::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) sub1::i#1 (byte) sub1::i#0
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) main::$1 [8] if((volatile byte) main::i!=rangelast(0,2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Resolved ranged next value [6] main::i ← ++ main::i to ++
Resolved ranged comparison value [8] if(main::i!=rangelast(0,2)) goto main::@1 to (number) 3
Adding number conversion cast (unumber) 3 in if((volatile byte) main::i!=(number) 3) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 3
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Calls in [main] to sub1:7
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @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()
(void()) main()
main: scope:[main] from @1
[4] (volatile byte) main::i ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) sub1::i#0 ← (volatile byte) main::i
[6] call sub1
[7] (byte) sub1::return#0 ← (byte) sub1::return#1
to:main::@2
main::@2: scope:[main] from main::@1
[8] (byte~) main::$0 ← (byte) sub1::return#0
[9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0
[10] (volatile byte) main::i ← ++ (volatile byte) main::i
[11] if((volatile byte) main::i!=(byte) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[12] return
to:@return
(byte()) sub1((byte) sub1::i)
sub1: scope:[sub1] from main::@1
[13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0
to:sub1::@return
sub1::@return: scope:[sub1] from sub1
[14] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte~) main::$0 202.0
(volatile byte) main::i loadstore 64.5
(byte()) sub1((byte) sub1::i)
(byte) sub1::i
(byte) sub1::i#0 2103.0
(byte) sub1::return
(byte) sub1::return#0 202.0
(byte) sub1::return#1 367.33333333333337
Initial phi equivalence classes
Added variable main::i to live range equivalence class [ main::i ]
Added variable sub1::i#0 to live range equivalence class [ sub1::i#0 ]
Added variable sub1::return#0 to live range equivalence class [ sub1::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable sub1::return#1 to live range equivalence class [ sub1::return#1 ]
Complete equivalence classes
[ main::i ]
[ sub1::i#0 ]
[ sub1::return#0 ]
[ main::$0 ]
[ sub1::return#1 ]
Allocated zp[1]:5 [ main::i ]
Allocated zp[1]:6 [ sub1::i#0 ]
Allocated zp[1]:7 [ sub1::return#0 ]
Allocated zp[1]:8 [ main::$0 ]
Allocated zp[1]:9 [ sub1::return#1 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Demonstrates a procedure reserving addresses on zeropage
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label SCREEN = $400
.label i = 5
.label __0 = 8
// [4] (volatile byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
jmp __b1
// main::@1
__b1:
// [5] (byte) sub1::i#0 ← (volatile byte) main::i -- vbuz1=vbuz2
lda.z i
sta.z sub1.i
// [6] call sub1
jsr sub1
// [7] (byte) sub1::return#0 ← (byte) sub1::return#1 -- vbuz1=vbuz2
lda.z sub1.return_1
sta.z sub1.return
jmp __b2
// main::@2
__b2:
// [8] (byte~) main::$0 ← (byte) sub1::return#0 -- vbuz1=vbuz2
lda.z sub1.return
sta.z __0
// [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2
lda.z __0
ldy.z i
sta SCREEN,y
// [10] (volatile byte) main::i ← ++ (volatile byte) main::i -- vbuz1=_inc_vbuz1
inc.z i
// [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp.z i
bne __b1
jmp __breturn
// main::@return
__breturn:
// [12] return
rts
}
// sub1
// sub1(byte zp(6) i)
sub1: {
.label i = 6
.label return = 7
.label return_1 = 9
// [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuz1=vbuz2_plus_vbuz2
lda.z i
asl
sta.z return_1
jmp __breturn
// sub1::@return
__breturn:
// [14] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (volatile byte) main::i ← (byte) 0 [ main::i ] ( main:2 [ main::i ] { } ) always clobbers reg byte a
Statement [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 [ main::i ] ( main:2 [ main::i ] { } ) always clobbers reg byte y
Statement [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 [ main::i ] ( main:2 [ main::i ] { } ) always clobbers reg byte a
Statement [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 [ sub1::return#1 ] ( main:2::sub1:6 [ main::i sub1::return#1 ] { { sub1::i#0 = main::i } { sub1::return#0 = sub1::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:5 [ main::i ] : zp[1]:5 ,
Potential registers zp[1]:6 [ sub1::i#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ sub1::return#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ main::$0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ sub1::return#1 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [sub1] 2,103: zp[1]:6 [ sub1::i#0 ] 367.33: zp[1]:9 [ sub1::return#1 ] 202: zp[1]:7 [ sub1::return#0 ]
Uplift Scope [main] 202: zp[1]:8 [ main::$0 ] 64.5: zp[1]:5 [ main::i ]
Uplift Scope []
Uplifting [sub1] best 452 combination reg byte a [ sub1::i#0 ] reg byte a [ sub1::return#1 ] reg byte a [ sub1::return#0 ]
Uplifting [main] best 392 combination reg byte a [ main::$0 ] zp[1]:5 [ main::i ]
Uplifting [] best 392 combination
Attempting to uplift remaining variables inzp[1]:5 [ main::i ]
Uplifting [main] best 392 combination zp[1]:5 [ main::i ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Demonstrates a procedure reserving addresses on zeropage
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label SCREEN = $400
.label i = 5
// [4] (volatile byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
jmp __b1
// main::@1
__b1:
// [5] (byte) sub1::i#0 ← (volatile byte) main::i -- vbuaa=vbuz1
lda.z i
// [6] call sub1
jsr sub1
// [7] (byte) sub1::return#0 ← (byte) sub1::return#1
jmp __b2
// main::@2
__b2:
// [8] (byte~) main::$0 ← (byte) sub1::return#0
// [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy.z i
sta SCREEN,y
// [10] (volatile byte) main::i ← ++ (volatile byte) main::i -- vbuz1=_inc_vbuz1
inc.z i
// [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp.z i
bne __b1
jmp __breturn
// main::@return
__breturn:
// [12] return
rts
}
// sub1
// sub1(byte register(A) i)
sub1: {
// [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
jmp __breturn
// sub1::@return
__breturn:
// [14] return
rts
}
// File Data
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
Removing instruction __b1_from___bbegin:
Removing instruction __b1:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bbegin:
Removing instruction __bend:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 202.0
(label) main::@1
(label) main::@2
(label) main::@return
(const nomodify byte*) main::SCREEN = (byte*) 1024
(volatile byte) main::i loadstore zp[1]:5 64.5
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 2103.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 202.0
(byte) sub1::return#1 reg byte a 367.33333333333337
zp[1]:5 [ main::i ]
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
// File Comments
// Demonstrates a procedure reserving addresses on zeropage
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label SCREEN = $400
.label i = 5
// for( volatile byte i : 0..2)
// [4] (volatile byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
// main::@1
__b1:
// sub1(i)
// [5] (byte) sub1::i#0 ← (volatile byte) main::i -- vbuaa=vbuz1
lda.z i
// [6] call sub1
jsr sub1
// [7] (byte) sub1::return#0 ← (byte) sub1::return#1
// main::@2
// [8] (byte~) main::$0 ← (byte) sub1::return#0
// SCREEN[i] = sub1(i)
// [9] *((const nomodify byte*) main::SCREEN + (volatile byte) main::i) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuaa
ldy.z i
sta SCREEN,y
// for( volatile byte i : 0..2)
// [10] (volatile byte) main::i ← ++ (volatile byte) main::i -- vbuz1=_inc_vbuz1
inc.z i
// [11] if((volatile byte) main::i!=(byte) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #3
cmp.z i
bne __b1
// main::@return
// }
// [12] return
rts
}
// sub1
// sub1(byte register(A) i)
sub1: {
// i+i
// [13] (byte) sub1::return#1 ← (byte) sub1::i#0 + (byte) sub1::i#0 -- vbuaa=vbuaa_plus_vbuaa
asl
// sub1::@return
// }
// [14] return
rts
}
// File Data

View File

@ -0,0 +1,23 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(byte~) main::$0 reg byte a 202.0
(label) main::@1
(label) main::@2
(label) main::@return
(const nomodify byte*) main::SCREEN = (byte*) 1024
(volatile byte) main::i loadstore zp[1]:5 64.5
(byte()) sub1((byte) sub1::i)
(label) sub1::@return
(byte) sub1::i
(byte) sub1::i#0 reg byte a 2103.0
(byte) sub1::return
(byte) sub1::return#0 reg byte a 202.0
(byte) sub1::return#1 reg byte a 367.33333333333337
zp[1]:5 [ main::i ]
reg byte a [ sub1::i#0 ]
reg byte a [ sub1::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ sub1::return#1 ]