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:
parent
d714c6ab4c
commit
978d85055a
@ -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
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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}.
|
||||
|
@ -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}.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#pragma reserve(0x16)
|
||||
#pragma zp_reserve(0x16)
|
||||
#pragma encoding(petscii_mixed)
|
||||
char strTemp[] = "v=X";
|
||||
int main(void){
|
||||
|
15
src/test/kc/reserve-zp-global-range.c
Normal file
15
src/test/kc/reserve-zp-global-range.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
16
src/test/kc/reserve-zp-procedure-4.c
Normal file
16
src/test/kc/reserve-zp-procedure-4.c
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
||||
|
32
src/test/ref/reserve-zp-global-range.asm
Normal file
32
src/test/ref/reserve-zp-global-range.asm
Normal 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
|
||||
}
|
36
src/test/ref/reserve-zp-global-range.cfg
Normal file
36
src/test/ref/reserve-zp-global-range.cfg
Normal 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
|
453
src/test/ref/reserve-zp-global-range.log
Normal file
453
src/test/ref/reserve-zp-global-range.log
Normal 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
|
||||
|
23
src/test/ref/reserve-zp-global-range.sym
Normal file
23
src/test/ref/reserve-zp-global-range.sym
Normal 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 ]
|
32
src/test/ref/reserve-zp-procedure-4.asm
Normal file
32
src/test/ref/reserve-zp-procedure-4.asm
Normal 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
|
||||
}
|
36
src/test/ref/reserve-zp-procedure-4.cfg
Normal file
36
src/test/ref/reserve-zp-procedure-4.cfg
Normal 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
|
453
src/test/ref/reserve-zp-procedure-4.log
Normal file
453
src/test/ref/reserve-zp-procedure-4.log
Normal 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
|
||||
|
23
src/test/ref/reserve-zp-procedure-4.sym
Normal file
23
src/test/ref/reserve-zp-procedure-4.sym
Normal 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 ]
|
Loading…
Reference in New Issue
Block a user