mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-08-15 13:27:36 +00:00
Added keyword for declaring memory-variables and properties on variable type. #328
This commit is contained in:
@@ -44,6 +44,27 @@ public abstract class SymbolVariable implements Symbol {
|
|||||||
/** Specifies that the variable must always be added to the output ASM even if it is never used anywhere. */
|
/** Specifies that the variable must always be added to the output ASM even if it is never used anywhere. */
|
||||||
private boolean declaredExport;
|
private boolean declaredExport;
|
||||||
|
|
||||||
|
/** Specifies that the variable must live in a register if possible (CPU register or ZP-address). */
|
||||||
|
private boolean declaredAsRegister;
|
||||||
|
|
||||||
|
/** Specifies that the variable must live in memory. */
|
||||||
|
private boolean declaredAsMemory;
|
||||||
|
|
||||||
|
/** Specifies a specific address where the variable must reside in memory. */
|
||||||
|
private Long declaredMemoryAddress;
|
||||||
|
|
||||||
|
/** Strategy being used for storing and accessing the variable. The value depends on the directives memory/register/volatile/const - and on the compilers optimization decisions.
|
||||||
|
* <ul>
|
||||||
|
* <li>REGISTER-variables are turned into versions and PHI-nodes are used for them throughout the entire program. They cannot be "volatile" and the "address-of" operator cannot be used on them.</li>
|
||||||
|
* <li>MEMORY-variables are stored in memory and accessed through load/store operators. They cannot be declared as "register".</li>
|
||||||
|
* <li>CONSTANT-variables are constant.
|
||||||
|
* </ul>
|
||||||
|
**/
|
||||||
|
public enum StorageStrategy { REGISTER, MEMORY, CONSTANT }
|
||||||
|
|
||||||
|
/** The storage strategy for the variable. */
|
||||||
|
private StorageStrategy storageStrategy;
|
||||||
|
|
||||||
/** Comments preceding the procedure in the source code. */
|
/** Comments preceding the procedure in the source code. */
|
||||||
private List<Comment> comments;
|
private List<Comment> comments;
|
||||||
|
|
||||||
@@ -53,6 +74,7 @@ public abstract class SymbolVariable implements Symbol {
|
|||||||
/** The data segment to put the variable into (if it is allocated in memory). */
|
/** The data segment to put the variable into (if it is allocated in memory). */
|
||||||
private String dataSegment;
|
private String dataSegment;
|
||||||
|
|
||||||
|
|
||||||
public SymbolVariable(String name, Scope scope, SymbolType type, String dataSegment) {
|
public SymbolVariable(String name, Scope scope, SymbolType type, String dataSegment) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
@@ -60,6 +82,7 @@ public abstract class SymbolVariable implements Symbol {
|
|||||||
this.inferredType = false;
|
this.inferredType = false;
|
||||||
this.comments = new ArrayList<>();
|
this.comments = new ArrayList<>();
|
||||||
this.dataSegment = dataSegment;
|
this.dataSegment = dataSegment;
|
||||||
|
this.storageStrategy = StorageStrategy.REGISTER;
|
||||||
setFullName();
|
setFullName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +213,38 @@ public abstract class SymbolVariable implements Symbol {
|
|||||||
this.declaredExport = declaredExport;
|
this.declaredExport = declaredExport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeclaredAsRegister() {
|
||||||
|
return declaredAsRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeclaredAsRegister(boolean declaredAsRegister) {
|
||||||
|
this.declaredAsRegister = declaredAsRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeclaredAsMemory() {
|
||||||
|
return declaredAsMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeclaredAsMemory(boolean declaredAsMemory) {
|
||||||
|
this.declaredAsMemory = declaredAsMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getDeclaredMemoryAddress() {
|
||||||
|
return declaredMemoryAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeclaredMemoryAddress(Long declaredMemoryAddress) {
|
||||||
|
this.declaredMemoryAddress = declaredMemoryAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageStrategy getStorageStrategy() {
|
||||||
|
return storageStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStorageStrategy(StorageStrategy storageStrategy) {
|
||||||
|
this.storageStrategy = storageStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Comment> getComments() {
|
public List<Comment> getComments() {
|
||||||
return comments;
|
return comments;
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ package dk.camelot64.kickc.model.symbols;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
|
|
||||||
/** A Symbol (variable, jump label, etc.) */
|
/** A Versioned variable. Versions are created for REGISTER-variables that are handled through PHI-nodes. */
|
||||||
public class VariableVersion extends Variable {
|
public class VariableVersion extends Variable {
|
||||||
|
|
||||||
private String versionOfName;
|
private String versionOfName;
|
||||||
@@ -10,7 +10,11 @@ public class VariableVersion extends Variable {
|
|||||||
public VariableVersion(VariableUnversioned versionOf, int version) {
|
public VariableVersion(VariableUnversioned versionOf, int version) {
|
||||||
super(versionOf.getLocalName() + "#" + version, versionOf.getScope(), versionOf.getType(), versionOf.getDataSegment());
|
super(versionOf.getLocalName() + "#" + version, versionOf.getScope(), versionOf.getType(), versionOf.getDataSegment());
|
||||||
this.setDeclaredAlignment(versionOf.getDeclaredAlignment());
|
this.setDeclaredAlignment(versionOf.getDeclaredAlignment());
|
||||||
|
this.setDeclaredAsRegister(versionOf.isDeclaredAsRegister());
|
||||||
|
this.setDeclaredAsMemory(versionOf.isDeclaredAsMemory());
|
||||||
this.setDeclaredRegister(versionOf.getDeclaredRegister());
|
this.setDeclaredRegister(versionOf.getDeclaredRegister());
|
||||||
|
this.setDeclaredMemoryAddress(versionOf.getDeclaredMemoryAddress());
|
||||||
|
this.setStorageStrategy(versionOf.getStorageStrategy());
|
||||||
this.setDeclaredVolatile(versionOf.isDeclaredVolatile());
|
this.setDeclaredVolatile(versionOf.isDeclaredVolatile());
|
||||||
this.setDeclaredExport(versionOf.isDeclaredExport());
|
this.setDeclaredExport(versionOf.isDeclaredExport());
|
||||||
this.setInferedVolatile(versionOf.isInferedVolatile());
|
this.setInferedVolatile(versionOf.isInferedVolatile());
|
||||||
|
@@ -78,6 +78,7 @@ EXTERN: 'extern' ;
|
|||||||
EXPORT: 'export' ;
|
EXPORT: 'export' ;
|
||||||
ALIGN: 'align' ;
|
ALIGN: 'align' ;
|
||||||
REGISTER: 'register' ;
|
REGISTER: 'register' ;
|
||||||
|
MEMORY: 'memory' ;
|
||||||
INLINE: 'inline' ;
|
INLINE: 'inline' ;
|
||||||
VOLATILE: 'volatile' ;
|
VOLATILE: 'volatile' ;
|
||||||
INTERRUPT: 'interrupt' ;
|
INTERRUPT: 'interrupt' ;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -51,89 +51,90 @@ EXTERN=50
|
|||||||
EXPORT=51
|
EXPORT=51
|
||||||
ALIGN=52
|
ALIGN=52
|
||||||
REGISTER=53
|
REGISTER=53
|
||||||
INLINE=54
|
MEMORY=54
|
||||||
VOLATILE=55
|
INLINE=55
|
||||||
INTERRUPT=56
|
VOLATILE=56
|
||||||
CALLING=57
|
INTERRUPT=57
|
||||||
CALLINGCONVENTION=58
|
CALLING=58
|
||||||
IF=59
|
CALLINGCONVENTION=59
|
||||||
ELSE=60
|
IF=60
|
||||||
WHILE=61
|
ELSE=61
|
||||||
DO=62
|
WHILE=62
|
||||||
FOR=63
|
DO=63
|
||||||
SWITCH=64
|
FOR=64
|
||||||
RETURN=65
|
SWITCH=65
|
||||||
BREAK=66
|
RETURN=66
|
||||||
CONTINUE=67
|
BREAK=67
|
||||||
ASM=68
|
CONTINUE=68
|
||||||
DEFAULT=69
|
ASM=69
|
||||||
CASE=70
|
DEFAULT=70
|
||||||
STRUCT=71
|
CASE=71
|
||||||
ENUM=72
|
STRUCT=72
|
||||||
SIZEOF=73
|
ENUM=73
|
||||||
TYPEID=74
|
SIZEOF=74
|
||||||
KICKASM=75
|
TYPEID=75
|
||||||
RESOURCE=76
|
KICKASM=76
|
||||||
USES=77
|
RESOURCE=77
|
||||||
CLOBBERS=78
|
USES=78
|
||||||
BYTES=79
|
CLOBBERS=79
|
||||||
CYCLES=80
|
BYTES=80
|
||||||
LOGIC_NOT=81
|
CYCLES=81
|
||||||
SIGNEDNESS=82
|
LOGIC_NOT=82
|
||||||
SIMPLETYPE=83
|
SIGNEDNESS=83
|
||||||
BOOLEAN=84
|
SIMPLETYPE=84
|
||||||
KICKASM_BODY=85
|
BOOLEAN=85
|
||||||
STRING=86
|
KICKASM_BODY=86
|
||||||
CHAR=87
|
STRING=87
|
||||||
NUMBER=88
|
CHAR=88
|
||||||
NUMFLOAT=89
|
NUMBER=89
|
||||||
BINFLOAT=90
|
NUMFLOAT=90
|
||||||
DECFLOAT=91
|
BINFLOAT=91
|
||||||
HEXFLOAT=92
|
DECFLOAT=92
|
||||||
NUMINT=93
|
HEXFLOAT=93
|
||||||
BININTEGER=94
|
NUMINT=94
|
||||||
DECINTEGER=95
|
BININTEGER=95
|
||||||
HEXINTEGER=96
|
DECINTEGER=96
|
||||||
NAME=97
|
HEXINTEGER=97
|
||||||
WS=98
|
NAME=98
|
||||||
COMMENT_LINE=99
|
WS=99
|
||||||
COMMENT_BLOCK=100
|
COMMENT_LINE=100
|
||||||
ASM_BYTE=101
|
COMMENT_BLOCK=101
|
||||||
ASM_MNEMONIC=102
|
ASM_BYTE=102
|
||||||
ASM_IMM=103
|
ASM_MNEMONIC=103
|
||||||
ASM_COLON=104
|
ASM_IMM=104
|
||||||
ASM_COMMA=105
|
ASM_COLON=105
|
||||||
ASM_PAR_BEGIN=106
|
ASM_COMMA=106
|
||||||
ASM_PAR_END=107
|
ASM_PAR_BEGIN=107
|
||||||
ASM_BRACKET_BEGIN=108
|
ASM_PAR_END=108
|
||||||
ASM_BRACKET_END=109
|
ASM_BRACKET_BEGIN=109
|
||||||
ASM_DOT=110
|
ASM_BRACKET_END=110
|
||||||
ASM_SHIFT_LEFT=111
|
ASM_DOT=111
|
||||||
ASM_SHIFT_RIGHT=112
|
ASM_SHIFT_LEFT=112
|
||||||
ASM_PLUS=113
|
ASM_SHIFT_RIGHT=113
|
||||||
ASM_MINUS=114
|
ASM_PLUS=114
|
||||||
ASM_LESS_THAN=115
|
ASM_MINUS=115
|
||||||
ASM_GREATER_THAN=116
|
ASM_LESS_THAN=116
|
||||||
ASM_MULTIPLY=117
|
ASM_GREATER_THAN=117
|
||||||
ASM_DIVIDE=118
|
ASM_MULTIPLY=118
|
||||||
ASM_CURLY_BEGIN=119
|
ASM_DIVIDE=119
|
||||||
ASM_CURLY_END=120
|
ASM_CURLY_BEGIN=120
|
||||||
ASM_NUMBER=121
|
ASM_CURLY_END=121
|
||||||
ASM_NUMFLOAT=122
|
ASM_NUMBER=122
|
||||||
ASM_BINFLOAT=123
|
ASM_NUMFLOAT=123
|
||||||
ASM_DECFLOAT=124
|
ASM_BINFLOAT=124
|
||||||
ASM_HEXFLOAT=125
|
ASM_DECFLOAT=125
|
||||||
ASM_NUMINT=126
|
ASM_HEXFLOAT=126
|
||||||
ASM_BININTEGER=127
|
ASM_NUMINT=127
|
||||||
ASM_DECINTEGER=128
|
ASM_BININTEGER=128
|
||||||
ASM_HEXINTEGER=129
|
ASM_DECINTEGER=129
|
||||||
ASM_CHAR=130
|
ASM_HEXINTEGER=130
|
||||||
ASM_MULTI_REL=131
|
ASM_CHAR=131
|
||||||
ASM_MULTI_NAME=132
|
ASM_MULTI_REL=132
|
||||||
ASM_NAME=133
|
ASM_MULTI_NAME=133
|
||||||
ASM_WS=134
|
ASM_NAME=134
|
||||||
ASM_COMMENT_LINE=135
|
ASM_WS=135
|
||||||
ASM_COMMENT_BLOCK=136
|
ASM_COMMENT_LINE=136
|
||||||
|
ASM_COMMENT_BLOCK=137
|
||||||
';'=8
|
';'=8
|
||||||
'..'=11
|
'..'=11
|
||||||
'?'=12
|
'?'=12
|
||||||
@@ -168,32 +169,33 @@ ASM_COMMENT_BLOCK=136
|
|||||||
'export'=51
|
'export'=51
|
||||||
'align'=52
|
'align'=52
|
||||||
'register'=53
|
'register'=53
|
||||||
'inline'=54
|
'memory'=54
|
||||||
'volatile'=55
|
'inline'=55
|
||||||
'interrupt'=56
|
'volatile'=56
|
||||||
'calling'=57
|
'interrupt'=57
|
||||||
'if'=59
|
'calling'=58
|
||||||
'else'=60
|
'if'=60
|
||||||
'while'=61
|
'else'=61
|
||||||
'do'=62
|
'while'=62
|
||||||
'for'=63
|
'do'=63
|
||||||
'switch'=64
|
'for'=64
|
||||||
'return'=65
|
'switch'=65
|
||||||
'break'=66
|
'return'=66
|
||||||
'continue'=67
|
'break'=67
|
||||||
'asm'=68
|
'continue'=68
|
||||||
'default'=69
|
'asm'=69
|
||||||
'case'=70
|
'default'=70
|
||||||
'struct'=71
|
'case'=71
|
||||||
'enum'=72
|
'struct'=72
|
||||||
'sizeof'=73
|
'enum'=73
|
||||||
'typeid'=74
|
'sizeof'=74
|
||||||
'kickasm'=75
|
'typeid'=75
|
||||||
'resource'=76
|
'kickasm'=76
|
||||||
'uses'=77
|
'resource'=77
|
||||||
'clobbers'=78
|
'uses'=78
|
||||||
'bytes'=79
|
'clobbers'=79
|
||||||
'cycles'=80
|
'bytes'=80
|
||||||
'!'=81
|
'cycles'=81
|
||||||
'.byte'=101
|
'!'=82
|
||||||
'#'=103
|
'.byte'=102
|
||||||
|
'#'=104
|
||||||
|
@@ -100,6 +100,7 @@ directive
|
|||||||
| EXPORT #directiveExport
|
| EXPORT #directiveExport
|
||||||
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
|
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
|
||||||
| REGISTER ( PAR_BEGIN ( NAME | NUMBER ) PAR_END)? #directiveRegister
|
| REGISTER ( PAR_BEGIN ( NAME | NUMBER ) PAR_END)? #directiveRegister
|
||||||
|
| MEMORY ( PAR_BEGIN ( NUMBER ) PAR_END)? #directiveMemory
|
||||||
| INLINE #directiveInline
|
| INLINE #directiveInline
|
||||||
| VOLATILE #directiveVolatile
|
| VOLATILE #directiveVolatile
|
||||||
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
|
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -51,89 +51,90 @@ EXTERN=50
|
|||||||
EXPORT=51
|
EXPORT=51
|
||||||
ALIGN=52
|
ALIGN=52
|
||||||
REGISTER=53
|
REGISTER=53
|
||||||
INLINE=54
|
MEMORY=54
|
||||||
VOLATILE=55
|
INLINE=55
|
||||||
INTERRUPT=56
|
VOLATILE=56
|
||||||
CALLING=57
|
INTERRUPT=57
|
||||||
CALLINGCONVENTION=58
|
CALLING=58
|
||||||
IF=59
|
CALLINGCONVENTION=59
|
||||||
ELSE=60
|
IF=60
|
||||||
WHILE=61
|
ELSE=61
|
||||||
DO=62
|
WHILE=62
|
||||||
FOR=63
|
DO=63
|
||||||
SWITCH=64
|
FOR=64
|
||||||
RETURN=65
|
SWITCH=65
|
||||||
BREAK=66
|
RETURN=66
|
||||||
CONTINUE=67
|
BREAK=67
|
||||||
ASM=68
|
CONTINUE=68
|
||||||
DEFAULT=69
|
ASM=69
|
||||||
CASE=70
|
DEFAULT=70
|
||||||
STRUCT=71
|
CASE=71
|
||||||
ENUM=72
|
STRUCT=72
|
||||||
SIZEOF=73
|
ENUM=73
|
||||||
TYPEID=74
|
SIZEOF=74
|
||||||
KICKASM=75
|
TYPEID=75
|
||||||
RESOURCE=76
|
KICKASM=76
|
||||||
USES=77
|
RESOURCE=77
|
||||||
CLOBBERS=78
|
USES=78
|
||||||
BYTES=79
|
CLOBBERS=79
|
||||||
CYCLES=80
|
BYTES=80
|
||||||
LOGIC_NOT=81
|
CYCLES=81
|
||||||
SIGNEDNESS=82
|
LOGIC_NOT=82
|
||||||
SIMPLETYPE=83
|
SIGNEDNESS=83
|
||||||
BOOLEAN=84
|
SIMPLETYPE=84
|
||||||
KICKASM_BODY=85
|
BOOLEAN=85
|
||||||
STRING=86
|
KICKASM_BODY=86
|
||||||
CHAR=87
|
STRING=87
|
||||||
NUMBER=88
|
CHAR=88
|
||||||
NUMFLOAT=89
|
NUMBER=89
|
||||||
BINFLOAT=90
|
NUMFLOAT=90
|
||||||
DECFLOAT=91
|
BINFLOAT=91
|
||||||
HEXFLOAT=92
|
DECFLOAT=92
|
||||||
NUMINT=93
|
HEXFLOAT=93
|
||||||
BININTEGER=94
|
NUMINT=94
|
||||||
DECINTEGER=95
|
BININTEGER=95
|
||||||
HEXINTEGER=96
|
DECINTEGER=96
|
||||||
NAME=97
|
HEXINTEGER=97
|
||||||
WS=98
|
NAME=98
|
||||||
COMMENT_LINE=99
|
WS=99
|
||||||
COMMENT_BLOCK=100
|
COMMENT_LINE=100
|
||||||
ASM_BYTE=101
|
COMMENT_BLOCK=101
|
||||||
ASM_MNEMONIC=102
|
ASM_BYTE=102
|
||||||
ASM_IMM=103
|
ASM_MNEMONIC=103
|
||||||
ASM_COLON=104
|
ASM_IMM=104
|
||||||
ASM_COMMA=105
|
ASM_COLON=105
|
||||||
ASM_PAR_BEGIN=106
|
ASM_COMMA=106
|
||||||
ASM_PAR_END=107
|
ASM_PAR_BEGIN=107
|
||||||
ASM_BRACKET_BEGIN=108
|
ASM_PAR_END=108
|
||||||
ASM_BRACKET_END=109
|
ASM_BRACKET_BEGIN=109
|
||||||
ASM_DOT=110
|
ASM_BRACKET_END=110
|
||||||
ASM_SHIFT_LEFT=111
|
ASM_DOT=111
|
||||||
ASM_SHIFT_RIGHT=112
|
ASM_SHIFT_LEFT=112
|
||||||
ASM_PLUS=113
|
ASM_SHIFT_RIGHT=113
|
||||||
ASM_MINUS=114
|
ASM_PLUS=114
|
||||||
ASM_LESS_THAN=115
|
ASM_MINUS=115
|
||||||
ASM_GREATER_THAN=116
|
ASM_LESS_THAN=116
|
||||||
ASM_MULTIPLY=117
|
ASM_GREATER_THAN=117
|
||||||
ASM_DIVIDE=118
|
ASM_MULTIPLY=118
|
||||||
ASM_CURLY_BEGIN=119
|
ASM_DIVIDE=119
|
||||||
ASM_CURLY_END=120
|
ASM_CURLY_BEGIN=120
|
||||||
ASM_NUMBER=121
|
ASM_CURLY_END=121
|
||||||
ASM_NUMFLOAT=122
|
ASM_NUMBER=122
|
||||||
ASM_BINFLOAT=123
|
ASM_NUMFLOAT=123
|
||||||
ASM_DECFLOAT=124
|
ASM_BINFLOAT=124
|
||||||
ASM_HEXFLOAT=125
|
ASM_DECFLOAT=125
|
||||||
ASM_NUMINT=126
|
ASM_HEXFLOAT=126
|
||||||
ASM_BININTEGER=127
|
ASM_NUMINT=127
|
||||||
ASM_DECINTEGER=128
|
ASM_BININTEGER=128
|
||||||
ASM_HEXINTEGER=129
|
ASM_DECINTEGER=129
|
||||||
ASM_CHAR=130
|
ASM_HEXINTEGER=130
|
||||||
ASM_MULTI_REL=131
|
ASM_CHAR=131
|
||||||
ASM_MULTI_NAME=132
|
ASM_MULTI_REL=132
|
||||||
ASM_NAME=133
|
ASM_MULTI_NAME=133
|
||||||
ASM_WS=134
|
ASM_NAME=134
|
||||||
ASM_COMMENT_LINE=135
|
ASM_WS=135
|
||||||
ASM_COMMENT_BLOCK=136
|
ASM_COMMENT_LINE=136
|
||||||
|
ASM_COMMENT_BLOCK=137
|
||||||
';'=8
|
';'=8
|
||||||
'..'=11
|
'..'=11
|
||||||
'?'=12
|
'?'=12
|
||||||
@@ -168,32 +169,33 @@ ASM_COMMENT_BLOCK=136
|
|||||||
'export'=51
|
'export'=51
|
||||||
'align'=52
|
'align'=52
|
||||||
'register'=53
|
'register'=53
|
||||||
'inline'=54
|
'memory'=54
|
||||||
'volatile'=55
|
'inline'=55
|
||||||
'interrupt'=56
|
'volatile'=56
|
||||||
'calling'=57
|
'interrupt'=57
|
||||||
'if'=59
|
'calling'=58
|
||||||
'else'=60
|
'if'=60
|
||||||
'while'=61
|
'else'=61
|
||||||
'do'=62
|
'while'=62
|
||||||
'for'=63
|
'do'=63
|
||||||
'switch'=64
|
'for'=64
|
||||||
'return'=65
|
'switch'=65
|
||||||
'break'=66
|
'return'=66
|
||||||
'continue'=67
|
'break'=67
|
||||||
'asm'=68
|
'continue'=68
|
||||||
'default'=69
|
'asm'=69
|
||||||
'case'=70
|
'default'=70
|
||||||
'struct'=71
|
'case'=71
|
||||||
'enum'=72
|
'struct'=72
|
||||||
'sizeof'=73
|
'enum'=73
|
||||||
'typeid'=74
|
'sizeof'=74
|
||||||
'kickasm'=75
|
'typeid'=75
|
||||||
'resource'=76
|
'kickasm'=76
|
||||||
'uses'=77
|
'resource'=77
|
||||||
'clobbers'=78
|
'uses'=78
|
||||||
'bytes'=79
|
'clobbers'=79
|
||||||
'cycles'=80
|
'bytes'=80
|
||||||
'!'=81
|
'cycles'=81
|
||||||
'.byte'=101
|
'!'=82
|
||||||
'#'=103
|
'.byte'=102
|
||||||
|
'#'=104
|
||||||
|
@@ -373,6 +373,18 @@ public class KickCParserBaseListener implements KickCParserListener {
|
|||||||
* <p>The default implementation does nothing.</p>
|
* <p>The default implementation does nothing.</p>
|
||||||
*/
|
*/
|
||||||
@Override public void exitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx) { }
|
@Override public void exitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx) { }
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* <p>The default implementation does nothing.</p>
|
||||||
|
*/
|
||||||
|
@Override public void enterDirectiveMemory(KickCParser.DirectiveMemoryContext ctx) { }
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* <p>The default implementation does nothing.</p>
|
||||||
|
*/
|
||||||
|
@Override public void exitDirectiveMemory(KickCParser.DirectiveMemoryContext ctx) { }
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
@@ -223,6 +223,13 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
|||||||
* {@link #visitChildren} on {@code ctx}.</p>
|
* {@link #visitChildren} on {@code ctx}.</p>
|
||||||
*/
|
*/
|
||||||
@Override public T visitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx) { return visitChildren(ctx); }
|
@Override public T visitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx) { return visitChildren(ctx); }
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* <p>The default implementation returns the result of calling
|
||||||
|
* {@link #visitChildren} on {@code ctx}.</p>
|
||||||
|
*/
|
||||||
|
@Override public T visitDirectiveMemory(KickCParser.DirectiveMemoryContext ctx) { return visitChildren(ctx); }
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
@@ -345,6 +345,18 @@ public interface KickCParserListener extends ParseTreeListener {
|
|||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
void exitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx);
|
void exitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx);
|
||||||
|
/**
|
||||||
|
* Enter a parse tree produced by the {@code directiveMemory}
|
||||||
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
* @param ctx the parse tree
|
||||||
|
*/
|
||||||
|
void enterDirectiveMemory(KickCParser.DirectiveMemoryContext ctx);
|
||||||
|
/**
|
||||||
|
* Exit a parse tree produced by the {@code directiveMemory}
|
||||||
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
* @param ctx the parse tree
|
||||||
|
*/
|
||||||
|
void exitDirectiveMemory(KickCParser.DirectiveMemoryContext ctx);
|
||||||
/**
|
/**
|
||||||
* Enter a parse tree produced by the {@code directiveInline}
|
* Enter a parse tree produced by the {@code directiveInline}
|
||||||
* labeled alternative in {@link KickCParser#directive}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
@@ -210,6 +210,13 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
|||||||
* @return the visitor result
|
* @return the visitor result
|
||||||
*/
|
*/
|
||||||
T visitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx);
|
T visitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx);
|
||||||
|
/**
|
||||||
|
* Visit a parse tree produced by the {@code directiveMemory}
|
||||||
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
* @param ctx the parse tree
|
||||||
|
* @return the visitor result
|
||||||
|
*/
|
||||||
|
T visitDirectiveMemory(KickCParser.DirectiveMemoryContext ctx);
|
||||||
/**
|
/**
|
||||||
* Visit a parse tree produced by the {@code directiveInline}
|
* Visit a parse tree produced by the {@code directiveInline}
|
||||||
* labeled alternative in {@link KickCParser#directive}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
@@ -261,6 +261,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
SymbolType type = declVarType;
|
SymbolType type = declVarType;
|
||||||
List<Directive> directives = declVarDirectives;
|
List<Directive> directives = declVarDirectives;
|
||||||
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment);
|
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment);
|
||||||
|
// Set initial storage strategy
|
||||||
|
param.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||||
// Add directives
|
// Add directives
|
||||||
addDirectives(param, type, directives, new StatementSource(ctx));
|
addDirectives(param, type, directives, new StatementSource(ctx));
|
||||||
exitDeclTypes();
|
exitDeclTypes();
|
||||||
@@ -617,6 +619,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
} catch(CompileError e) {
|
} catch(CompileError e) {
|
||||||
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
||||||
}
|
}
|
||||||
|
// Set initial storage strategy
|
||||||
|
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||||
// Add directives
|
// Add directives
|
||||||
addDirectives(lValue, type, directives, new StatementSource(ctx));
|
addDirectives(lValue, type, directives, new StatementSource(ctx));
|
||||||
// Array / String variables are implicitly constant
|
// Array / String variables are implicitly constant
|
||||||
@@ -679,6 +683,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
for(Directive directive : directives) {
|
for(Directive directive : directives) {
|
||||||
if(directive instanceof DirectiveConst) {
|
if(directive instanceof DirectiveConst) {
|
||||||
lValue.setDeclaredConstant(true);
|
lValue.setDeclaredConstant(true);
|
||||||
|
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
|
||||||
} else if(directive instanceof DirectiveVolatile) {
|
} else if(directive instanceof DirectiveVolatile) {
|
||||||
lValue.setDeclaredVolatile(true);
|
lValue.setDeclaredVolatile(true);
|
||||||
} else if(directive instanceof DirectiveExport) {
|
} else if(directive instanceof DirectiveExport) {
|
||||||
@@ -689,8 +694,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
} else {
|
} else {
|
||||||
throw new CompileError("Error! Cannot align variable that is not a string or an array " + lValue.toString(program), source);
|
throw new CompileError("Error! Cannot align variable that is not a string or an array " + lValue.toString(program), source);
|
||||||
}
|
}
|
||||||
|
} else if(directive instanceof DirectiveMemory) {
|
||||||
|
DirectiveMemory directiveMemory = (DirectiveMemory) directive;
|
||||||
|
lValue.setDeclaredAsMemory(true);
|
||||||
|
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.MEMORY);
|
||||||
|
if(directiveMemory.address!=null) {
|
||||||
|
lValue.setDeclaredMemoryAddress(directiveMemory.address);
|
||||||
|
}
|
||||||
} else if(directive instanceof DirectiveRegister) {
|
} else if(directive instanceof DirectiveRegister) {
|
||||||
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
||||||
|
lValue.setDeclaredAsRegister(true);
|
||||||
|
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||||
if(directiveRegister.name != null) {
|
if(directiveRegister.name != null) {
|
||||||
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
||||||
Registers.Register register = Registers.getRegister(directiveRegister.name);
|
Registers.Register register = Registers.getRegister(directiveRegister.name);
|
||||||
@@ -818,6 +832,20 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitDirectiveMemory(KickCParser.DirectiveMemoryContext ctx) {
|
||||||
|
if(ctx.NUMBER() != null) {
|
||||||
|
try {
|
||||||
|
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
|
||||||
|
return new DirectiveRegister(memoryAddress.getInteger());
|
||||||
|
} catch(NumberFormatException e) {
|
||||||
|
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new DirectiveRegister(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Directive visitDirectiveVolatile(KickCParser.DirectiveVolatileContext ctx) {
|
public Directive visitDirectiveVolatile(KickCParser.DirectiveVolatileContext ctx) {
|
||||||
return new DirectiveVolatile();
|
return new DirectiveVolatile();
|
||||||
@@ -1178,6 +1206,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
} catch(CompileError e) {
|
} catch(CompileError e) {
|
||||||
throw new CompileError(e.getMessage(), statementSource);
|
throw new CompileError(e.getMessage(), statementSource);
|
||||||
}
|
}
|
||||||
|
// Set initial storage strategy
|
||||||
|
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||||
// Add directives
|
// Add directives
|
||||||
addDirectives(lValue, varType, varDirectives, statementSource);
|
addDirectives(lValue, varType, varDirectives, statementSource);
|
||||||
} else {
|
} else {
|
||||||
@@ -2219,6 +2249,23 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Variable memory allocation. */
|
||||||
|
private static class DirectiveMemory implements Directive {
|
||||||
|
|
||||||
|
/** Optional hard-coded address to use for storing the variable. */
|
||||||
|
private Long address;
|
||||||
|
|
||||||
|
public DirectiveMemory() {
|
||||||
|
this.address = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectiveMemory(long address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Reservation of zero-page addresses */
|
/** Reservation of zero-page addresses */
|
||||||
private static class DirectiveReserveZp implements Directive {
|
private static class DirectiveReserveZp implements Directive {
|
||||||
List<Integer> reservedZp;
|
List<Integer> reservedZp;
|
||||||
|
@@ -304,7 +304,11 @@ public class Pass1ProcedureInline extends Pass1Base {
|
|||||||
inlineVar.setInferredType(procVar.isInferredType());
|
inlineVar.setInferredType(procVar.isInferredType());
|
||||||
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
|
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
|
||||||
inlineVar.setDeclaredConstant(procVar.isDeclaredConstant());
|
inlineVar.setDeclaredConstant(procVar.isDeclaredConstant());
|
||||||
|
inlineVar.setDeclaredAsRegister(procVar.isDeclaredAsRegister());
|
||||||
|
inlineVar.setDeclaredAsMemory(procVar.isDeclaredAsMemory());
|
||||||
inlineVar.setDeclaredRegister(procVar.getDeclaredRegister());
|
inlineVar.setDeclaredRegister(procVar.getDeclaredRegister());
|
||||||
|
inlineVar.setDeclaredMemoryAddress(procVar.getDeclaredMemoryAddress());
|
||||||
|
inlineVar.setStorageStrategy(procVar.getStorageStrategy());
|
||||||
inlineVar.setDeclaredVolatile(procVar.isDeclaredVolatile());
|
inlineVar.setDeclaredVolatile(procVar.isDeclaredVolatile());
|
||||||
inlineVar.setInferedVolatile(procVar.isInferedVolatile());
|
inlineVar.setInferedVolatile(procVar.isInferedVolatile());
|
||||||
inlineVar.setDeclaredExport(procVar.isDeclaredExport());
|
inlineVar.setDeclaredExport(procVar.isDeclaredExport());
|
||||||
|
@@ -84,7 +84,11 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
|||||||
|
|
||||||
constantVar.setInferredType(variable.isInferredType());
|
constantVar.setInferredType(variable.isInferredType());
|
||||||
constantVar.setDeclaredAlignment(variable.getDeclaredAlignment());
|
constantVar.setDeclaredAlignment(variable.getDeclaredAlignment());
|
||||||
|
constantVar.setDeclaredAsRegister(variable.isDeclaredAsRegister());
|
||||||
constantVar.setDeclaredRegister(variable.getDeclaredRegister());
|
constantVar.setDeclaredRegister(variable.getDeclaredRegister());
|
||||||
|
constantVar.setDeclaredAsMemory(variable.isDeclaredAsMemory());
|
||||||
|
constantVar.setDeclaredMemoryAddress(variable.getDeclaredMemoryAddress());
|
||||||
|
constantVar.setStorageStrategy(variable.getStorageStrategy());
|
||||||
constantVar.setDeclaredExport(variable.isDeclaredExport());
|
constantVar.setDeclaredExport(variable.isDeclaredExport());
|
||||||
if(variable.getComments().size() > 0) {
|
if(variable.getComments().size() > 0) {
|
||||||
constantVar.setComments(variable.getComments());
|
constantVar.setComments(variable.getComments());
|
||||||
|
@@ -40,7 +40,7 @@ public class Pass2IdenticalPhiElimination extends Pass2SsaOptimization {
|
|||||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||||
if(phiRValue.getrValue() instanceof SymbolVariableRef) {
|
if(phiRValue.getrValue() instanceof SymbolVariableRef) {
|
||||||
SymbolVariable symbolVar = (SymbolVariable) getScope().getSymbol((SymbolVariableRef) phiRValue.getrValue());
|
SymbolVariable symbolVar = (SymbolVariable) getScope().getSymbol((SymbolVariableRef) phiRValue.getrValue());
|
||||||
if(symbolVar.getDeclaredRegister() !=null) {
|
if(symbolVar.getDeclaredRegister() != null) { //TODO: Handle register/memory/storage strategy differently!
|
||||||
// Do not collapse PHI's for variables with declared registers (this prevents procedure parameters from being turned into constants)
|
// Do not collapse PHI's for variables with declared registers (this prevents procedure parameters from being turned into constants)
|
||||||
identical = false;
|
identical = false;
|
||||||
break;
|
break;
|
||||||
|
@@ -60,11 +60,11 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getCallingDepth(ScopeRef currentScope, List<ScopeRef> path) {
|
private int getCallingDepth(ScopeRef currentScope, List<ScopeRef> path) {
|
||||||
|
// Avoid infinite recursion
|
||||||
if(path.contains(currentScope))
|
if(path.contains(currentScope))
|
||||||
return 10;
|
return 10;
|
||||||
List<ScopeRef> myPath = new ArrayList<>(path);
|
path = new ArrayList<>(path);
|
||||||
myPath.add(currentScope);
|
path.add(currentScope);
|
||||||
|
|
||||||
int callingDepth = 1;
|
int callingDepth = 1;
|
||||||
Collection<ScopeRef> callingScopes = callGraph.getCallingBlocks(currentScope);
|
Collection<ScopeRef> callingScopes = callGraph.getCallingBlocks(currentScope);
|
||||||
@@ -88,7 +88,7 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Also look through all callers
|
// Also look through all callers
|
||||||
int superCallingDepth = getCallingDepth(callingScope, myPath);
|
int superCallingDepth = getCallingDepth(callingScope, path);
|
||||||
if(superCallingDepth>callingDepth) {
|
if(superCallingDepth>callingDepth) {
|
||||||
callingDepth= superCallingDepth;
|
callingDepth= superCallingDepth;
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ public class Pass4RegisterUpliftPotentialInitialize extends Pass2Base {
|
|||||||
Registers.Register declaredRegister = null;
|
Registers.Register declaredRegister = null;
|
||||||
for(VariableRef varRef : equivalenceClass.getVariables()) {
|
for(VariableRef varRef : equivalenceClass.getVariables()) {
|
||||||
Variable variable = getProgram().getScope().getVariable(varRef);
|
Variable variable = getProgram().getScope().getVariable(varRef);
|
||||||
if(variable.getDeclaredRegister() != null) {
|
if(variable.getDeclaredRegister() != null) { //TODO: Handle register/memory/storage strategy differently!
|
||||||
if(declaredRegister != null && !declaredRegister.equals(variable.getDeclaredRegister())) {
|
if(declaredRegister != null && !declaredRegister.equals(variable.getDeclaredRegister())) {
|
||||||
throw new CompileError("Equivalence class has variables with different declared registers \n" +
|
throw new CompileError("Equivalence class has variables with different declared registers \n" +
|
||||||
" - equivalence class: " + equivalenceClass.toString(true) + "\n" +
|
" - equivalence class: " + equivalenceClass.toString(true) + "\n" +
|
||||||
|
@@ -40,7 +40,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
}
|
}
|
||||||
// Add all ZP's declared hardcoded register for a live variable
|
// Add all ZP's declared hardcoded register for a live variable
|
||||||
for(Variable variable : getSymbols().getAllVariables(true)) {
|
for(Variable variable : getSymbols().getAllVariables(true)) {
|
||||||
if(variable.getDeclaredRegister() instanceof Registers.RegisterZpDeclared) {
|
if(variable.getDeclaredRegister() instanceof Registers.RegisterZpDeclared) { //TODO: Handle register/memory/storage strategy differently!
|
||||||
int zp = ((Registers.RegisterZpDeclared) variable.getDeclaredRegister()).getZp();
|
int zp = ((Registers.RegisterZpDeclared) variable.getDeclaredRegister()).getZp();
|
||||||
int sizeBytes = variable.getType().getSizeBytes();
|
int sizeBytes = variable.getType().getSizeBytes();
|
||||||
for(int i=0;i<sizeBytes; i++) {
|
for(int i=0;i<sizeBytes; i++) {
|
||||||
@@ -56,9 +56,8 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
for(LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
for(LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||||
for(VariableRef variableRef : equivalenceClass.getVariables()) {
|
for(VariableRef variableRef : equivalenceClass.getVariables()) {
|
||||||
Variable variable = getProgram().getScope().getVariable(variableRef);
|
Variable variable = getProgram().getScope().getVariable(variableRef);
|
||||||
Registers.Register declaredRegister = variable.getDeclaredRegister();
|
Registers.Register declaredRegister = variable.getDeclaredRegister(); //TODO: Handle register/memory/storage strategy differently!
|
||||||
if(declaredRegister !=null) {
|
if(declaredRegister !=null) {
|
||||||
|
|
||||||
if(declaredRegister instanceof Registers.RegisterZpDeclared) {
|
if(declaredRegister instanceof Registers.RegisterZpDeclared) {
|
||||||
if(declaredRegister.getType().equals(Registers.RegisterType.ZP_VAR)) {
|
if(declaredRegister.getType().equals(Registers.RegisterType.ZP_VAR)) {
|
||||||
Registers.RegisterType registerType = getRegisterType(variable);
|
Registers.RegisterType registerType = getRegisterType(variable);
|
||||||
|
@@ -232,7 +232,11 @@ public class Unroller {
|
|||||||
if(definedVarRef.isIntermediate()) {
|
if(definedVarRef.isIntermediate()) {
|
||||||
newVar = definedVar.getScope().addVariableIntermediate();
|
newVar = definedVar.getScope().addVariableIntermediate();
|
||||||
newVar.setType(definedVar.getType());
|
newVar.setType(definedVar.getType());
|
||||||
|
newVar.setDeclaredAsRegister(definedVar.isDeclaredAsRegister());
|
||||||
newVar.setDeclaredRegister(definedVar.getDeclaredRegister());
|
newVar.setDeclaredRegister(definedVar.getDeclaredRegister());
|
||||||
|
newVar.setDeclaredAsMemory(definedVar.isDeclaredAsMemory());
|
||||||
|
newVar.setDeclaredMemoryAddress(definedVar.getDeclaredMemoryAddress());
|
||||||
|
newVar.setStorageStrategy(definedVar.getStorageStrategy());
|
||||||
newVar.setDeclaredVolatile(definedVar.isDeclaredVolatile());
|
newVar.setDeclaredVolatile(definedVar.isDeclaredVolatile());
|
||||||
newVar.setInferedVolatile(definedVar.isInferedVolatile());
|
newVar.setInferedVolatile(definedVar.isInferedVolatile());
|
||||||
newVar.setDeclaredExport(definedVar.isDeclaredExport());
|
newVar.setDeclaredExport(definedVar.isDeclaredExport());
|
||||||
|
Reference in New Issue
Block a user