mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-16 08:33:37 +00:00
Added keyword for declaring memory-variables and properties on variable type. #328
This commit is contained in:
parent
7a59390644
commit
d312edf024
@ -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. */
|
||||
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. */
|
||||
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). */
|
||||
private String dataSegment;
|
||||
|
||||
|
||||
public SymbolVariable(String name, Scope scope, SymbolType type, String dataSegment) {
|
||||
this.name = name;
|
||||
this.scope = scope;
|
||||
@ -60,6 +82,7 @@ public abstract class SymbolVariable implements Symbol {
|
||||
this.inferredType = false;
|
||||
this.comments = new ArrayList<>();
|
||||
this.dataSegment = dataSegment;
|
||||
this.storageStrategy = StorageStrategy.REGISTER;
|
||||
setFullName();
|
||||
}
|
||||
|
||||
@ -190,6 +213,38 @@ public abstract class SymbolVariable implements Symbol {
|
||||
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() {
|
||||
return comments;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.model.symbols;
|
||||
|
||||
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 {
|
||||
|
||||
private String versionOfName;
|
||||
@ -10,7 +10,11 @@ public class VariableVersion extends Variable {
|
||||
public VariableVersion(VariableUnversioned versionOf, int version) {
|
||||
super(versionOf.getLocalName() + "#" + version, versionOf.getScope(), versionOf.getType(), versionOf.getDataSegment());
|
||||
this.setDeclaredAlignment(versionOf.getDeclaredAlignment());
|
||||
this.setDeclaredAsRegister(versionOf.isDeclaredAsRegister());
|
||||
this.setDeclaredAsMemory(versionOf.isDeclaredAsMemory());
|
||||
this.setDeclaredRegister(versionOf.getDeclaredRegister());
|
||||
this.setDeclaredMemoryAddress(versionOf.getDeclaredMemoryAddress());
|
||||
this.setStorageStrategy(versionOf.getStorageStrategy());
|
||||
this.setDeclaredVolatile(versionOf.isDeclaredVolatile());
|
||||
this.setDeclaredExport(versionOf.isDeclaredExport());
|
||||
this.setInferedVolatile(versionOf.isInferedVolatile());
|
||||
|
@ -78,6 +78,7 @@ EXTERN: 'extern' ;
|
||||
EXPORT: 'export' ;
|
||||
ALIGN: 'align' ;
|
||||
REGISTER: 'register' ;
|
||||
MEMORY: 'memory' ;
|
||||
INLINE: 'inline' ;
|
||||
VOLATILE: 'volatile' ;
|
||||
INTERRUPT: 'interrupt' ;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,89 +51,90 @@ EXTERN=50
|
||||
EXPORT=51
|
||||
ALIGN=52
|
||||
REGISTER=53
|
||||
INLINE=54
|
||||
VOLATILE=55
|
||||
INTERRUPT=56
|
||||
CALLING=57
|
||||
CALLINGCONVENTION=58
|
||||
IF=59
|
||||
ELSE=60
|
||||
WHILE=61
|
||||
DO=62
|
||||
FOR=63
|
||||
SWITCH=64
|
||||
RETURN=65
|
||||
BREAK=66
|
||||
CONTINUE=67
|
||||
ASM=68
|
||||
DEFAULT=69
|
||||
CASE=70
|
||||
STRUCT=71
|
||||
ENUM=72
|
||||
SIZEOF=73
|
||||
TYPEID=74
|
||||
KICKASM=75
|
||||
RESOURCE=76
|
||||
USES=77
|
||||
CLOBBERS=78
|
||||
BYTES=79
|
||||
CYCLES=80
|
||||
LOGIC_NOT=81
|
||||
SIGNEDNESS=82
|
||||
SIMPLETYPE=83
|
||||
BOOLEAN=84
|
||||
KICKASM_BODY=85
|
||||
STRING=86
|
||||
CHAR=87
|
||||
NUMBER=88
|
||||
NUMFLOAT=89
|
||||
BINFLOAT=90
|
||||
DECFLOAT=91
|
||||
HEXFLOAT=92
|
||||
NUMINT=93
|
||||
BININTEGER=94
|
||||
DECINTEGER=95
|
||||
HEXINTEGER=96
|
||||
NAME=97
|
||||
WS=98
|
||||
COMMENT_LINE=99
|
||||
COMMENT_BLOCK=100
|
||||
ASM_BYTE=101
|
||||
ASM_MNEMONIC=102
|
||||
ASM_IMM=103
|
||||
ASM_COLON=104
|
||||
ASM_COMMA=105
|
||||
ASM_PAR_BEGIN=106
|
||||
ASM_PAR_END=107
|
||||
ASM_BRACKET_BEGIN=108
|
||||
ASM_BRACKET_END=109
|
||||
ASM_DOT=110
|
||||
ASM_SHIFT_LEFT=111
|
||||
ASM_SHIFT_RIGHT=112
|
||||
ASM_PLUS=113
|
||||
ASM_MINUS=114
|
||||
ASM_LESS_THAN=115
|
||||
ASM_GREATER_THAN=116
|
||||
ASM_MULTIPLY=117
|
||||
ASM_DIVIDE=118
|
||||
ASM_CURLY_BEGIN=119
|
||||
ASM_CURLY_END=120
|
||||
ASM_NUMBER=121
|
||||
ASM_NUMFLOAT=122
|
||||
ASM_BINFLOAT=123
|
||||
ASM_DECFLOAT=124
|
||||
ASM_HEXFLOAT=125
|
||||
ASM_NUMINT=126
|
||||
ASM_BININTEGER=127
|
||||
ASM_DECINTEGER=128
|
||||
ASM_HEXINTEGER=129
|
||||
ASM_CHAR=130
|
||||
ASM_MULTI_REL=131
|
||||
ASM_MULTI_NAME=132
|
||||
ASM_NAME=133
|
||||
ASM_WS=134
|
||||
ASM_COMMENT_LINE=135
|
||||
ASM_COMMENT_BLOCK=136
|
||||
MEMORY=54
|
||||
INLINE=55
|
||||
VOLATILE=56
|
||||
INTERRUPT=57
|
||||
CALLING=58
|
||||
CALLINGCONVENTION=59
|
||||
IF=60
|
||||
ELSE=61
|
||||
WHILE=62
|
||||
DO=63
|
||||
FOR=64
|
||||
SWITCH=65
|
||||
RETURN=66
|
||||
BREAK=67
|
||||
CONTINUE=68
|
||||
ASM=69
|
||||
DEFAULT=70
|
||||
CASE=71
|
||||
STRUCT=72
|
||||
ENUM=73
|
||||
SIZEOF=74
|
||||
TYPEID=75
|
||||
KICKASM=76
|
||||
RESOURCE=77
|
||||
USES=78
|
||||
CLOBBERS=79
|
||||
BYTES=80
|
||||
CYCLES=81
|
||||
LOGIC_NOT=82
|
||||
SIGNEDNESS=83
|
||||
SIMPLETYPE=84
|
||||
BOOLEAN=85
|
||||
KICKASM_BODY=86
|
||||
STRING=87
|
||||
CHAR=88
|
||||
NUMBER=89
|
||||
NUMFLOAT=90
|
||||
BINFLOAT=91
|
||||
DECFLOAT=92
|
||||
HEXFLOAT=93
|
||||
NUMINT=94
|
||||
BININTEGER=95
|
||||
DECINTEGER=96
|
||||
HEXINTEGER=97
|
||||
NAME=98
|
||||
WS=99
|
||||
COMMENT_LINE=100
|
||||
COMMENT_BLOCK=101
|
||||
ASM_BYTE=102
|
||||
ASM_MNEMONIC=103
|
||||
ASM_IMM=104
|
||||
ASM_COLON=105
|
||||
ASM_COMMA=106
|
||||
ASM_PAR_BEGIN=107
|
||||
ASM_PAR_END=108
|
||||
ASM_BRACKET_BEGIN=109
|
||||
ASM_BRACKET_END=110
|
||||
ASM_DOT=111
|
||||
ASM_SHIFT_LEFT=112
|
||||
ASM_SHIFT_RIGHT=113
|
||||
ASM_PLUS=114
|
||||
ASM_MINUS=115
|
||||
ASM_LESS_THAN=116
|
||||
ASM_GREATER_THAN=117
|
||||
ASM_MULTIPLY=118
|
||||
ASM_DIVIDE=119
|
||||
ASM_CURLY_BEGIN=120
|
||||
ASM_CURLY_END=121
|
||||
ASM_NUMBER=122
|
||||
ASM_NUMFLOAT=123
|
||||
ASM_BINFLOAT=124
|
||||
ASM_DECFLOAT=125
|
||||
ASM_HEXFLOAT=126
|
||||
ASM_NUMINT=127
|
||||
ASM_BININTEGER=128
|
||||
ASM_DECINTEGER=129
|
||||
ASM_HEXINTEGER=130
|
||||
ASM_CHAR=131
|
||||
ASM_MULTI_REL=132
|
||||
ASM_MULTI_NAME=133
|
||||
ASM_NAME=134
|
||||
ASM_WS=135
|
||||
ASM_COMMENT_LINE=136
|
||||
ASM_COMMENT_BLOCK=137
|
||||
';'=8
|
||||
'..'=11
|
||||
'?'=12
|
||||
@ -168,32 +169,33 @@ ASM_COMMENT_BLOCK=136
|
||||
'export'=51
|
||||
'align'=52
|
||||
'register'=53
|
||||
'inline'=54
|
||||
'volatile'=55
|
||||
'interrupt'=56
|
||||
'calling'=57
|
||||
'if'=59
|
||||
'else'=60
|
||||
'while'=61
|
||||
'do'=62
|
||||
'for'=63
|
||||
'switch'=64
|
||||
'return'=65
|
||||
'break'=66
|
||||
'continue'=67
|
||||
'asm'=68
|
||||
'default'=69
|
||||
'case'=70
|
||||
'struct'=71
|
||||
'enum'=72
|
||||
'sizeof'=73
|
||||
'typeid'=74
|
||||
'kickasm'=75
|
||||
'resource'=76
|
||||
'uses'=77
|
||||
'clobbers'=78
|
||||
'bytes'=79
|
||||
'cycles'=80
|
||||
'!'=81
|
||||
'.byte'=101
|
||||
'#'=103
|
||||
'memory'=54
|
||||
'inline'=55
|
||||
'volatile'=56
|
||||
'interrupt'=57
|
||||
'calling'=58
|
||||
'if'=60
|
||||
'else'=61
|
||||
'while'=62
|
||||
'do'=63
|
||||
'for'=64
|
||||
'switch'=65
|
||||
'return'=66
|
||||
'break'=67
|
||||
'continue'=68
|
||||
'asm'=69
|
||||
'default'=70
|
||||
'case'=71
|
||||
'struct'=72
|
||||
'enum'=73
|
||||
'sizeof'=74
|
||||
'typeid'=75
|
||||
'kickasm'=76
|
||||
'resource'=77
|
||||
'uses'=78
|
||||
'clobbers'=79
|
||||
'bytes'=80
|
||||
'cycles'=81
|
||||
'!'=82
|
||||
'.byte'=102
|
||||
'#'=104
|
||||
|
@ -100,6 +100,7 @@ directive
|
||||
| EXPORT #directiveExport
|
||||
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
|
||||
| REGISTER ( PAR_BEGIN ( NAME | NUMBER ) PAR_END)? #directiveRegister
|
||||
| MEMORY ( PAR_BEGIN ( NUMBER ) PAR_END)? #directiveMemory
|
||||
| INLINE #directiveInline
|
||||
| VOLATILE #directiveVolatile
|
||||
| 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
|
||||
ALIGN=52
|
||||
REGISTER=53
|
||||
INLINE=54
|
||||
VOLATILE=55
|
||||
INTERRUPT=56
|
||||
CALLING=57
|
||||
CALLINGCONVENTION=58
|
||||
IF=59
|
||||
ELSE=60
|
||||
WHILE=61
|
||||
DO=62
|
||||
FOR=63
|
||||
SWITCH=64
|
||||
RETURN=65
|
||||
BREAK=66
|
||||
CONTINUE=67
|
||||
ASM=68
|
||||
DEFAULT=69
|
||||
CASE=70
|
||||
STRUCT=71
|
||||
ENUM=72
|
||||
SIZEOF=73
|
||||
TYPEID=74
|
||||
KICKASM=75
|
||||
RESOURCE=76
|
||||
USES=77
|
||||
CLOBBERS=78
|
||||
BYTES=79
|
||||
CYCLES=80
|
||||
LOGIC_NOT=81
|
||||
SIGNEDNESS=82
|
||||
SIMPLETYPE=83
|
||||
BOOLEAN=84
|
||||
KICKASM_BODY=85
|
||||
STRING=86
|
||||
CHAR=87
|
||||
NUMBER=88
|
||||
NUMFLOAT=89
|
||||
BINFLOAT=90
|
||||
DECFLOAT=91
|
||||
HEXFLOAT=92
|
||||
NUMINT=93
|
||||
BININTEGER=94
|
||||
DECINTEGER=95
|
||||
HEXINTEGER=96
|
||||
NAME=97
|
||||
WS=98
|
||||
COMMENT_LINE=99
|
||||
COMMENT_BLOCK=100
|
||||
ASM_BYTE=101
|
||||
ASM_MNEMONIC=102
|
||||
ASM_IMM=103
|
||||
ASM_COLON=104
|
||||
ASM_COMMA=105
|
||||
ASM_PAR_BEGIN=106
|
||||
ASM_PAR_END=107
|
||||
ASM_BRACKET_BEGIN=108
|
||||
ASM_BRACKET_END=109
|
||||
ASM_DOT=110
|
||||
ASM_SHIFT_LEFT=111
|
||||
ASM_SHIFT_RIGHT=112
|
||||
ASM_PLUS=113
|
||||
ASM_MINUS=114
|
||||
ASM_LESS_THAN=115
|
||||
ASM_GREATER_THAN=116
|
||||
ASM_MULTIPLY=117
|
||||
ASM_DIVIDE=118
|
||||
ASM_CURLY_BEGIN=119
|
||||
ASM_CURLY_END=120
|
||||
ASM_NUMBER=121
|
||||
ASM_NUMFLOAT=122
|
||||
ASM_BINFLOAT=123
|
||||
ASM_DECFLOAT=124
|
||||
ASM_HEXFLOAT=125
|
||||
ASM_NUMINT=126
|
||||
ASM_BININTEGER=127
|
||||
ASM_DECINTEGER=128
|
||||
ASM_HEXINTEGER=129
|
||||
ASM_CHAR=130
|
||||
ASM_MULTI_REL=131
|
||||
ASM_MULTI_NAME=132
|
||||
ASM_NAME=133
|
||||
ASM_WS=134
|
||||
ASM_COMMENT_LINE=135
|
||||
ASM_COMMENT_BLOCK=136
|
||||
MEMORY=54
|
||||
INLINE=55
|
||||
VOLATILE=56
|
||||
INTERRUPT=57
|
||||
CALLING=58
|
||||
CALLINGCONVENTION=59
|
||||
IF=60
|
||||
ELSE=61
|
||||
WHILE=62
|
||||
DO=63
|
||||
FOR=64
|
||||
SWITCH=65
|
||||
RETURN=66
|
||||
BREAK=67
|
||||
CONTINUE=68
|
||||
ASM=69
|
||||
DEFAULT=70
|
||||
CASE=71
|
||||
STRUCT=72
|
||||
ENUM=73
|
||||
SIZEOF=74
|
||||
TYPEID=75
|
||||
KICKASM=76
|
||||
RESOURCE=77
|
||||
USES=78
|
||||
CLOBBERS=79
|
||||
BYTES=80
|
||||
CYCLES=81
|
||||
LOGIC_NOT=82
|
||||
SIGNEDNESS=83
|
||||
SIMPLETYPE=84
|
||||
BOOLEAN=85
|
||||
KICKASM_BODY=86
|
||||
STRING=87
|
||||
CHAR=88
|
||||
NUMBER=89
|
||||
NUMFLOAT=90
|
||||
BINFLOAT=91
|
||||
DECFLOAT=92
|
||||
HEXFLOAT=93
|
||||
NUMINT=94
|
||||
BININTEGER=95
|
||||
DECINTEGER=96
|
||||
HEXINTEGER=97
|
||||
NAME=98
|
||||
WS=99
|
||||
COMMENT_LINE=100
|
||||
COMMENT_BLOCK=101
|
||||
ASM_BYTE=102
|
||||
ASM_MNEMONIC=103
|
||||
ASM_IMM=104
|
||||
ASM_COLON=105
|
||||
ASM_COMMA=106
|
||||
ASM_PAR_BEGIN=107
|
||||
ASM_PAR_END=108
|
||||
ASM_BRACKET_BEGIN=109
|
||||
ASM_BRACKET_END=110
|
||||
ASM_DOT=111
|
||||
ASM_SHIFT_LEFT=112
|
||||
ASM_SHIFT_RIGHT=113
|
||||
ASM_PLUS=114
|
||||
ASM_MINUS=115
|
||||
ASM_LESS_THAN=116
|
||||
ASM_GREATER_THAN=117
|
||||
ASM_MULTIPLY=118
|
||||
ASM_DIVIDE=119
|
||||
ASM_CURLY_BEGIN=120
|
||||
ASM_CURLY_END=121
|
||||
ASM_NUMBER=122
|
||||
ASM_NUMFLOAT=123
|
||||
ASM_BINFLOAT=124
|
||||
ASM_DECFLOAT=125
|
||||
ASM_HEXFLOAT=126
|
||||
ASM_NUMINT=127
|
||||
ASM_BININTEGER=128
|
||||
ASM_DECINTEGER=129
|
||||
ASM_HEXINTEGER=130
|
||||
ASM_CHAR=131
|
||||
ASM_MULTI_REL=132
|
||||
ASM_MULTI_NAME=133
|
||||
ASM_NAME=134
|
||||
ASM_WS=135
|
||||
ASM_COMMENT_LINE=136
|
||||
ASM_COMMENT_BLOCK=137
|
||||
';'=8
|
||||
'..'=11
|
||||
'?'=12
|
||||
@ -168,32 +169,33 @@ ASM_COMMENT_BLOCK=136
|
||||
'export'=51
|
||||
'align'=52
|
||||
'register'=53
|
||||
'inline'=54
|
||||
'volatile'=55
|
||||
'interrupt'=56
|
||||
'calling'=57
|
||||
'if'=59
|
||||
'else'=60
|
||||
'while'=61
|
||||
'do'=62
|
||||
'for'=63
|
||||
'switch'=64
|
||||
'return'=65
|
||||
'break'=66
|
||||
'continue'=67
|
||||
'asm'=68
|
||||
'default'=69
|
||||
'case'=70
|
||||
'struct'=71
|
||||
'enum'=72
|
||||
'sizeof'=73
|
||||
'typeid'=74
|
||||
'kickasm'=75
|
||||
'resource'=76
|
||||
'uses'=77
|
||||
'clobbers'=78
|
||||
'bytes'=79
|
||||
'cycles'=80
|
||||
'!'=81
|
||||
'.byte'=101
|
||||
'#'=103
|
||||
'memory'=54
|
||||
'inline'=55
|
||||
'volatile'=56
|
||||
'interrupt'=57
|
||||
'calling'=58
|
||||
'if'=60
|
||||
'else'=61
|
||||
'while'=62
|
||||
'do'=63
|
||||
'for'=64
|
||||
'switch'=65
|
||||
'return'=66
|
||||
'break'=67
|
||||
'continue'=68
|
||||
'asm'=69
|
||||
'default'=70
|
||||
'case'=71
|
||||
'struct'=72
|
||||
'enum'=73
|
||||
'sizeof'=74
|
||||
'typeid'=75
|
||||
'kickasm'=76
|
||||
'resource'=77
|
||||
'uses'=78
|
||||
'clobbers'=79
|
||||
'bytes'=80
|
||||
'cycles'=81
|
||||
'!'=82
|
||||
'.byte'=102
|
||||
'#'=104
|
||||
|
@ -373,6 +373,18 @@ public class KickCParserBaseListener implements KickCParserListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@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}
|
||||
*
|
||||
|
@ -223,6 +223,13 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@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}
|
||||
*
|
||||
|
@ -345,6 +345,18 @@ public interface KickCParserListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
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}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
|
@ -210,6 +210,13 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
||||
* @return the visitor result
|
||||
*/
|
||||
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}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
|
@ -261,6 +261,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
SymbolType type = declVarType;
|
||||
List<Directive> directives = declVarDirectives;
|
||||
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment);
|
||||
// Set initial storage strategy
|
||||
param.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||
// Add directives
|
||||
addDirectives(param, type, directives, new StatementSource(ctx));
|
||||
exitDeclTypes();
|
||||
@ -617,6 +619,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} catch(CompileError e) {
|
||||
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
||||
}
|
||||
// Set initial storage strategy
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||
// Add directives
|
||||
addDirectives(lValue, type, directives, new StatementSource(ctx));
|
||||
// Array / String variables are implicitly constant
|
||||
@ -679,6 +683,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
for(Directive directive : directives) {
|
||||
if(directive instanceof DirectiveConst) {
|
||||
lValue.setDeclaredConstant(true);
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
|
||||
} else if(directive instanceof DirectiveVolatile) {
|
||||
lValue.setDeclaredVolatile(true);
|
||||
} else if(directive instanceof DirectiveExport) {
|
||||
@ -689,8 +694,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else {
|
||||
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) {
|
||||
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
||||
lValue.setDeclaredAsRegister(true);
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||
if(directiveRegister.name != null) {
|
||||
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
||||
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
|
||||
public Directive visitDirectiveVolatile(KickCParser.DirectiveVolatileContext ctx) {
|
||||
return new DirectiveVolatile();
|
||||
@ -1178,6 +1206,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} catch(CompileError e) {
|
||||
throw new CompileError(e.getMessage(), statementSource);
|
||||
}
|
||||
// Set initial storage strategy
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.REGISTER);
|
||||
// Add directives
|
||||
addDirectives(lValue, varType, varDirectives, statementSource);
|
||||
} 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 */
|
||||
private static class DirectiveReserveZp implements Directive {
|
||||
List<Integer> reservedZp;
|
||||
|
@ -304,7 +304,11 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
inlineVar.setInferredType(procVar.isInferredType());
|
||||
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
|
||||
inlineVar.setDeclaredConstant(procVar.isDeclaredConstant());
|
||||
inlineVar.setDeclaredAsRegister(procVar.isDeclaredAsRegister());
|
||||
inlineVar.setDeclaredAsMemory(procVar.isDeclaredAsMemory());
|
||||
inlineVar.setDeclaredRegister(procVar.getDeclaredRegister());
|
||||
inlineVar.setDeclaredMemoryAddress(procVar.getDeclaredMemoryAddress());
|
||||
inlineVar.setStorageStrategy(procVar.getStorageStrategy());
|
||||
inlineVar.setDeclaredVolatile(procVar.isDeclaredVolatile());
|
||||
inlineVar.setInferedVolatile(procVar.isInferedVolatile());
|
||||
inlineVar.setDeclaredExport(procVar.isDeclaredExport());
|
||||
|
@ -84,7 +84,11 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
|
||||
constantVar.setInferredType(variable.isInferredType());
|
||||
constantVar.setDeclaredAlignment(variable.getDeclaredAlignment());
|
||||
constantVar.setDeclaredAsRegister(variable.isDeclaredAsRegister());
|
||||
constantVar.setDeclaredRegister(variable.getDeclaredRegister());
|
||||
constantVar.setDeclaredAsMemory(variable.isDeclaredAsMemory());
|
||||
constantVar.setDeclaredMemoryAddress(variable.getDeclaredMemoryAddress());
|
||||
constantVar.setStorageStrategy(variable.getStorageStrategy());
|
||||
constantVar.setDeclaredExport(variable.isDeclaredExport());
|
||||
if(variable.getComments().size() > 0) {
|
||||
constantVar.setComments(variable.getComments());
|
||||
|
@ -40,7 +40,7 @@ public class Pass2IdenticalPhiElimination extends Pass2SsaOptimization {
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(phiRValue.getrValue() instanceof SymbolVariableRef) {
|
||||
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)
|
||||
identical = false;
|
||||
break;
|
||||
|
@ -60,11 +60,11 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
|
||||
}
|
||||
|
||||
private int getCallingDepth(ScopeRef currentScope, List<ScopeRef> path) {
|
||||
|
||||
// Avoid infinite recursion
|
||||
if(path.contains(currentScope))
|
||||
return 10;
|
||||
List<ScopeRef> myPath = new ArrayList<>(path);
|
||||
myPath.add(currentScope);
|
||||
path = new ArrayList<>(path);
|
||||
path.add(currentScope);
|
||||
|
||||
int callingDepth = 1;
|
||||
Collection<ScopeRef> callingScopes = callGraph.getCallingBlocks(currentScope);
|
||||
@ -88,7 +88,7 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
|
||||
}
|
||||
}
|
||||
// Also look through all callers
|
||||
int superCallingDepth = getCallingDepth(callingScope, myPath);
|
||||
int superCallingDepth = getCallingDepth(callingScope, path);
|
||||
if(superCallingDepth>callingDepth) {
|
||||
callingDepth= superCallingDepth;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class Pass4RegisterUpliftPotentialInitialize extends Pass2Base {
|
||||
Registers.Register declaredRegister = null;
|
||||
for(VariableRef varRef : equivalenceClass.getVariables()) {
|
||||
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())) {
|
||||
throw new CompileError("Equivalence class has variables with different declared registers \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
|
||||
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 sizeBytes = variable.getType().getSizeBytes();
|
||||
for(int i=0;i<sizeBytes; i++) {
|
||||
@ -56,9 +56,8 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
for(LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||
for(VariableRef variableRef : equivalenceClass.getVariables()) {
|
||||
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 instanceof Registers.RegisterZpDeclared) {
|
||||
if(declaredRegister.getType().equals(Registers.RegisterType.ZP_VAR)) {
|
||||
Registers.RegisterType registerType = getRegisterType(variable);
|
||||
|
@ -232,7 +232,11 @@ public class Unroller {
|
||||
if(definedVarRef.isIntermediate()) {
|
||||
newVar = definedVar.getScope().addVariableIntermediate();
|
||||
newVar.setType(definedVar.getType());
|
||||
newVar.setDeclaredAsRegister(definedVar.isDeclaredAsRegister());
|
||||
newVar.setDeclaredRegister(definedVar.getDeclaredRegister());
|
||||
newVar.setDeclaredAsMemory(definedVar.isDeclaredAsMemory());
|
||||
newVar.setDeclaredMemoryAddress(definedVar.getDeclaredMemoryAddress());
|
||||
newVar.setStorageStrategy(definedVar.getStorageStrategy());
|
||||
newVar.setDeclaredVolatile(definedVar.isDeclaredVolatile());
|
||||
newVar.setInferedVolatile(definedVar.isInferedVolatile());
|
||||
newVar.setDeclaredExport(definedVar.isDeclaredExport());
|
||||
|
Loading…
x
Reference in New Issue
Block a user