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

View File

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

View File

@ -661,6 +661,18 @@ public class KickCParserBaseListener implements KickCParserListener {
* <p>The default implementation does nothing.</p>
*/
@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}
*

View File

@ -391,6 +391,13 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
* {@link #visitChildren} on {@code ctx}.</p>
*/
@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}
*

View File

@ -615,6 +615,16 @@ public interface KickCParserListener extends ParseTreeListener {
* @param ctx the parse tree
*/
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}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -369,6 +369,12 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
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}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -155,15 +155,40 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Object visitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) {
List<Integer> reservedZps = new ArrayList<>();
for(TerminalNode reservedNum : ctx.NUMBER()) {
Number reservedZp = NumberParser.parseLiteral(reservedNum.getText());
reservedZps.add(reservedZp.intValue());
}
final List<KickCParser.DirectiveReserveParamContext> reserveParams = ctx.directiveReserveParam();
List<Integer> reservedZps = getReservedZps(reserveParams);
program.addReservedZps(reservedZps);
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
public Object visitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) {
try {
@ -1155,11 +1180,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Directive visitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) {
List<Integer> reservedZps = new ArrayList<>();
for(TerminalNode reservedNum : ctx.NUMBER()) {
int reservedZp = NumberParser.parseLiteral(reservedNum.getText()).intValue();
reservedZps.add(reservedZp);
}
final List<KickCParser.DirectiveReserveParamContext> reserveParams = ctx.directiveReserveParam();
final List<Integer> reservedZps = getReservedZps(reserveParams);
return new Directive.ReserveZp(reservedZps);
}

View File

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

View File

@ -7,7 +7,7 @@
// Data
#pragma data_seg(Data)
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[] = {
@ -47,7 +47,6 @@ char SPRITE_C[] = {
0
};
// Variables
#pragma data_seg(Vars)
// Counts frames
@ -66,12 +65,8 @@ void main() {
TIA->COLUP0 = 0xf0;
// - Graphics
TIA->GRP0 = 0xaf;
// Player 1
// - Color
//TIA->COLUP1 = 0xf0;
// - Graphics
//TIA->GRP1 = 0xf5;
// - Size
TIA->NUSIZ0 = 0x05;
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
#pragma reserve(0x07, 0x0d, 0x0e, 0x12)
#pragma zp_reserve(0x07, 0x0d, 0x0e, 0x12)
// Generate a sinus table using BASIC floats
// - 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)
char strTemp[] = "v=X";
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
#pragma reserve(2,5)
#pragma zp_reserve(2,5)
void main() {
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;
}

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;
}

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;
}
reserve(5, 6, 7) byte sub2(byte i) {
__zp_reserve(5, 6, 7) byte sub2(byte 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;
}
reserve(5, 6, 7) byte sub2(byte i) {
__zp_reserve(5, 6, 7) byte sub2(byte i) {
return i+i+i;
}

View File

@ -0,0 +1,16 @@
// Demonstrates a procedure reserving addresses on zeropage
void main() {
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 <print.h>
#pragma reserve(08)
#pragma zp_reserve(08)
byte* const CHARSET = 0x2000;
byte* const SCREEN = 0x2800;

View File

@ -1,7 +1,7 @@
// Tests warning when running out of zeropage-addresses for variables
// 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
void main() {

View File

@ -16,6 +16,7 @@
.const CYCLES_PER_SCANLINE = $4c
.const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = 6
.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_ATARI_TIA_WRITE_WSYNC = 2
.const OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = $2a
@ -45,15 +46,14 @@ main: {
// - Graphics
lda #$af
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0
// TIA->NUSIZ0 = 0x05
// - Size
lda #5
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0
lda #$39
sta idx2
lda #0
sta idx
// Player 1
// - Color
//TIA->COLUP1 = 0xf0;
// - Graphics
//TIA->GRP1 = 0xf5;
__b2:
// TIA->VSYNC = 2
// Vertical Sync
@ -198,7 +198,7 @@ main: {
}
.segment Data
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
.segment Vars

View File

@ -13,73 +13,74 @@ main: scope:[main] from @1
asm { cld }
[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
[7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0) ← (byte) 5
to:main::@1
main::@1: scope:[main] from main main::@13
[7] (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) idx2#2 ← phi( main/(byte) $39 main::@13/(byte) idx2#1 )
[8] (byte) idx#2 ← phi( main/(byte) 0 main::@13/(byte) idx#1 )
to:main::@2
main::@2: scope:[main] from main::@1
[8] *((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 ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2
[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
[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
[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 }
[15] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2)
[16] (byte) idx#1 ← ++ (byte) idx#2
[17] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2)
[18] (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_HMOVE) ← (byte) 0
[16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2)
[17] (byte) idx#1 ← ++ (byte) idx#2
[18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2)
[19] (byte) idx2#1 ← ++ (byte) idx2#2
[20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0
to:main::@3
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
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_COLUBK) ← (byte) 0
[23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0
[24] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
to:main::@6
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 )
[24] (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
[25] (byte) main::p0_idx#4 ← phi( main::@10/(byte) main::p0_idx#8 main::@5/(byte) 0 )
[25] (byte) main::i#2 ← phi( main::@10/(byte) main::i#1 main::@5/(byte) 1 )
[26] if((byte) main::i#2<(byte) $c0) goto main::@7
to:main::@8
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_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 MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40
[27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2
[29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
[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
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
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
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_COLUBK) ← (byte) main::i#2
[34] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9
[33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
[34] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::i#2
[35] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9
to:main::@11
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
main::@15: scope:[main] from main::@11
[36] phi()
[37] phi()
to:main::@10
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::i#1 ← ++ (byte) main::i#2
[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 )
[39] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@6
main::@9: scope:[main] from main::@7
[39] (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] if((byte) main::gfx#0==(byte) 0) goto main::@10
[40] (byte) main::gfx#0 ← *((const byte*) SPRITE_C + (byte) main::p0_idx#4)
[41] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) main::gfx#0
[42] if((byte) main::gfx#0==(byte) 0) goto main::@10
to:main::@12
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
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

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_GRP0 = (byte) $1b
(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_WSYNC = (byte) 2
(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM = (byte) 4
(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T = (byte) $16
(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 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#4 reg byte y 500.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#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 ]