1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-27 04:49:27 +00:00

Added __notconst directive.

This commit is contained in:
jespergravgaard 2019-10-20 20:01:38 +02:00
parent ea4563cf99
commit a34abcbdff
35 changed files with 1875 additions and 1723 deletions

View File

@ -67,7 +67,7 @@ public class ControlFlowGraph implements Serializable {
}
/**
* Get the assignment of the passed variable.
* Get the assignment of the passed variable. Assumes that only a single assignment exists.
*
* @param variable The variable to find the assignment for
* @return The assignment. null if the variable is not assigned. The variable is assigned by a Phi-statement instead.
@ -87,7 +87,28 @@ public class ControlFlowGraph implements Serializable {
}
/**
* Get the block containing the assignment of the passed variable.
* Get all assignments of the passed variable.
*
* @param variable The variable to find the assignment for
* @return All assignments.
*/
public List<StatementLValue> getAssignments(VariableRef variable) {
ArrayList<StatementLValue> assignments = new ArrayList<>();
for(ControlFlowBlock block : getAllBlocks()) {
for(Statement statement : block.getStatements()) {
if(statement instanceof StatementLValue) {
StatementLValue assignment = (StatementLValue) statement;
if(variable.equals(assignment.getlValue())) {
assignments.add(assignment);
}
}
}
}
return assignments;
}
/**
* Get the block containing the assignment of the passed variable. Assumes that only a single assignment exists.
*
* @param variable The variable to find the assignment for
* @return The block containing the assignment. null if the variable is not assigned.

View File

@ -9,8 +9,16 @@ import java.util.List;
public interface Directive {
/** Variable declared constant. */
/** Variable declared const, __notconst or __maybeconst. */
class Const implements Directive {
/** The const declaration. */
SymbolVariable.ConstantDeclaration constantDeclaration;
public Const(SymbolVariable.ConstantDeclaration constantDeclaration) {
this.constantDeclaration = constantDeclaration;
}
}
/** Function with specific declared calling convention. */

View File

@ -135,7 +135,7 @@ public class DirectiveParserContext {
//this.defaultDirectives.add(new Directive.Register(true, null));
this.registerImpliesDirectives = new ArrayList<>();
this.typeDirectives = new HashMap<>();
this.typeDirectives.put(DirectiveType.ARRAY, Arrays.asList(new Directive.Const(), new Directive.MemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null), new Directive.Register(false, null)));
this.typeDirectives.put(DirectiveType.ARRAY, Arrays.asList(new Directive.Const(SymbolVariable.ConstantDeclaration.CONST), new Directive.MemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null)));
//this.typeDirectives.put(DirectiveType.POINTER, Arrays.asList(new Directive.MemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null)));
this.scopeDirectives = new HashMap<>();
this.scopeTypeDirectives = new HashMap<>();
@ -165,10 +165,12 @@ public class DirectiveParserContext {
Directive.Const constDirective = findDirective(Directive.Const.class, sourceDirectives, directiveScope, directiveType);
if(constDirective != null) {
lValue.setDeclaredConstant(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
if(!(lValue.getType() instanceof SymbolTypePointer))
lValue.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
lValue.setConstantDeclaration(constDirective.constantDeclaration);
if(SymbolVariable.ConstantDeclaration.CONST.equals(constDirective.constantDeclaration)) {
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
if(!(lValue.getType() instanceof SymbolTypePointer))
lValue.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
}
}
Directive.Volatile volatileDirective = findDirective(Directive.Volatile.class, sourceDirectives, directiveScope, directiveType);

View File

@ -26,8 +26,13 @@ public abstract class SymbolVariable implements Symbol {
/** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. */
private String asmName;
/** Specifies whether the symbol is declared to be constant, never constant or maybe constant. */
public enum ConstantDeclaration {
CONST, NOT_CONST, MAYBE_CONST
}
/** Specifies that the variable is declared a constant. It will be replaced by a ConstantVar when possible. */
private boolean declaredConstant;
private ConstantDeclaration constantDeclaration;
/** Specifies that the variable must be aligned in memory. Only allowed for arrays & strings. */
private Integer declaredAlignment;
@ -87,6 +92,7 @@ public abstract class SymbolVariable implements Symbol {
this.dataSegment = dataSegment;
this.storageStrategy = storageStrategy;
this.memoryArea = memoryArea;
this.constantDeclaration = ConstantDeclaration.MAYBE_CONST;
setFullName();
}
@ -165,12 +171,20 @@ public abstract class SymbolVariable implements Symbol {
}
}
public boolean isDeclaredConstant() {
return declaredConstant;
public void setConstantDeclaration(ConstantDeclaration constantDeclaration) {
this.constantDeclaration = constantDeclaration;
}
public void setDeclaredConstant(boolean declaredConstant) {
this.declaredConstant = declaredConstant;
public ConstantDeclaration getConstantDeclaration() {
return constantDeclaration;
}
public boolean isDeclaredConstant() {
return ConstantDeclaration.CONST.equals(constantDeclaration);
}
public boolean isDeclaredNotConstant() {
return ConstantDeclaration.NOT_CONST.equals(constantDeclaration);
}
public Integer getDeclaredAlignment() {
@ -206,7 +220,7 @@ public abstract class SymbolVariable implements Symbol {
}
public boolean isVolatile() {
return declaredVolatile || inferedVolatile || isStorageLoadStore();
return declaredVolatile || inferedVolatile;
}
public boolean isDeclaredExport() {

View File

@ -74,11 +74,12 @@ CODESEG:'code_seg';
DATASEG:'data_seg';
ENCODING:'encoding';
CONST: 'const' ;
NOTCONST: '__notconst' ;
MAYBECONST: '__maybeconst' ;
EXTERN: 'extern' ;
EXPORT: 'export' ;
ALIGN: 'align' ;
REGISTER: 'register' ;
NOTREGISTER: '__notregister' ;
ADDRESS: '__address' ;
ADDRESS_ZEROPAGE: '__zp' ;
ADDRESS_MAINMEM: '__mem' ;

File diff suppressed because it is too large Load Diff

View File

@ -47,100 +47,101 @@ CODESEG=46
DATASEG=47
ENCODING=48
CONST=49
EXTERN=50
EXPORT=51
ALIGN=52
REGISTER=53
NOTREGISTER=54
ADDRESS=55
ADDRESS_ZEROPAGE=56
ADDRESS_MAINMEM=57
FORM_SSA=58
FORM_NOTSSA=59
INLINE=60
VOLATILE=61
NOTVOLATILE=62
INTERRUPT=63
CALLING=64
CALLINGCONVENTION=65
IF=66
ELSE=67
WHILE=68
DO=69
FOR=70
SWITCH=71
RETURN=72
BREAK=73
CONTINUE=74
ASM=75
DEFAULT=76
CASE=77
STRUCT=78
ENUM=79
SIZEOF=80
TYPEID=81
KICKASM=82
RESOURCE=83
USES=84
CLOBBERS=85
BYTES=86
CYCLES=87
LOGIC_NOT=88
SIGNEDNESS=89
SIMPLETYPE=90
BOOLEAN=91
KICKASM_BODY=92
STRING=93
CHAR=94
NUMBER=95
NUMFLOAT=96
BINFLOAT=97
DECFLOAT=98
HEXFLOAT=99
NUMINT=100
BININTEGER=101
DECINTEGER=102
HEXINTEGER=103
NAME=104
WS=105
COMMENT_LINE=106
COMMENT_BLOCK=107
ASM_BYTE=108
ASM_MNEMONIC=109
ASM_IMM=110
ASM_COLON=111
ASM_COMMA=112
ASM_PAR_BEGIN=113
ASM_PAR_END=114
ASM_BRACKET_BEGIN=115
ASM_BRACKET_END=116
ASM_DOT=117
ASM_SHIFT_LEFT=118
ASM_SHIFT_RIGHT=119
ASM_PLUS=120
ASM_MINUS=121
ASM_LESS_THAN=122
ASM_GREATER_THAN=123
ASM_MULTIPLY=124
ASM_DIVIDE=125
ASM_CURLY_BEGIN=126
ASM_CURLY_END=127
ASM_NUMBER=128
ASM_NUMFLOAT=129
ASM_BINFLOAT=130
ASM_DECFLOAT=131
ASM_HEXFLOAT=132
ASM_NUMINT=133
ASM_BININTEGER=134
ASM_DECINTEGER=135
ASM_HEXINTEGER=136
ASM_CHAR=137
ASM_MULTI_REL=138
ASM_MULTI_NAME=139
ASM_NAME=140
ASM_WS=141
ASM_COMMENT_LINE=142
ASM_COMMENT_BLOCK=143
NOTCONST=50
MAYBECONST=51
EXTERN=52
EXPORT=53
ALIGN=54
REGISTER=55
ADDRESS=56
ADDRESS_ZEROPAGE=57
ADDRESS_MAINMEM=58
FORM_SSA=59
FORM_NOTSSA=60
INLINE=61
VOLATILE=62
NOTVOLATILE=63
INTERRUPT=64
CALLING=65
CALLINGCONVENTION=66
IF=67
ELSE=68
WHILE=69
DO=70
FOR=71
SWITCH=72
RETURN=73
BREAK=74
CONTINUE=75
ASM=76
DEFAULT=77
CASE=78
STRUCT=79
ENUM=80
SIZEOF=81
TYPEID=82
KICKASM=83
RESOURCE=84
USES=85
CLOBBERS=86
BYTES=87
CYCLES=88
LOGIC_NOT=89
SIGNEDNESS=90
SIMPLETYPE=91
BOOLEAN=92
KICKASM_BODY=93
STRING=94
CHAR=95
NUMBER=96
NUMFLOAT=97
BINFLOAT=98
DECFLOAT=99
HEXFLOAT=100
NUMINT=101
BININTEGER=102
DECINTEGER=103
HEXINTEGER=104
NAME=105
WS=106
COMMENT_LINE=107
COMMENT_BLOCK=108
ASM_BYTE=109
ASM_MNEMONIC=110
ASM_IMM=111
ASM_COLON=112
ASM_COMMA=113
ASM_PAR_BEGIN=114
ASM_PAR_END=115
ASM_BRACKET_BEGIN=116
ASM_BRACKET_END=117
ASM_DOT=118
ASM_SHIFT_LEFT=119
ASM_SHIFT_RIGHT=120
ASM_PLUS=121
ASM_MINUS=122
ASM_LESS_THAN=123
ASM_GREATER_THAN=124
ASM_MULTIPLY=125
ASM_DIVIDE=126
ASM_CURLY_BEGIN=127
ASM_CURLY_END=128
ASM_NUMBER=129
ASM_NUMFLOAT=130
ASM_BINFLOAT=131
ASM_DECFLOAT=132
ASM_HEXFLOAT=133
ASM_NUMINT=134
ASM_BININTEGER=135
ASM_DECINTEGER=136
ASM_HEXINTEGER=137
ASM_CHAR=138
ASM_MULTI_REL=139
ASM_MULTI_NAME=140
ASM_NAME=141
ASM_WS=142
ASM_COMMENT_LINE=143
ASM_COMMENT_BLOCK=144
';'=8
'..'=11
'?'=12
@ -171,43 +172,44 @@ ASM_COMMENT_BLOCK=143
'data_seg'=47
'encoding'=48
'const'=49
'extern'=50
'export'=51
'align'=52
'register'=53
'__notregister'=54
'__address'=55
'__zp'=56
'__mem'=57
'__ssa'=58
'__notssa'=59
'inline'=60
'volatile'=61
'__notvolatile'=62
'interrupt'=63
'calling'=64
'if'=66
'else'=67
'while'=68
'do'=69
'for'=70
'switch'=71
'return'=72
'break'=73
'continue'=74
'asm'=75
'default'=76
'case'=77
'struct'=78
'enum'=79
'sizeof'=80
'typeid'=81
'kickasm'=82
'resource'=83
'uses'=84
'clobbers'=85
'bytes'=86
'cycles'=87
'!'=88
'.byte'=108
'#'=110
'__notconst'=50
'__maybeconst'=51
'extern'=52
'export'=53
'align'=54
'register'=55
'__address'=56
'__zp'=57
'__mem'=58
'__ssa'=59
'__notssa'=60
'inline'=61
'volatile'=62
'__notvolatile'=63
'interrupt'=64
'calling'=65
'if'=67
'else'=68
'while'=69
'do'=70
'for'=71
'switch'=72
'return'=73
'break'=74
'continue'=75
'asm'=76
'default'=77
'case'=78
'struct'=79
'enum'=80
'sizeof'=81
'typeid'=82
'kickasm'=83
'resource'=84
'uses'=85
'clobbers'=86
'bytes'=87
'cycles'=88
'!'=89
'.byte'=109
'#'=111

View File

@ -96,11 +96,12 @@ globalDirective
directive
: CONST #directiveConst
| NOTCONST #directiveNotConst
| MAYBECONST #directiveMaybeConst
| EXTERN #directiveExtern
| EXPORT #directiveExport
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
| REGISTER ( PAR_BEGIN ( NAME ) PAR_END)? #directiveRegister
| NOTREGISTER #directiveNotRegister
| ADDRESS_ZEROPAGE #directiveMemoryAreaZp
| ADDRESS_MAINMEM #directiveMemoryAreaMain
| ADDRESS PAR_BEGIN ( NUMBER ) PAR_END #directiveMemoryAreaAddress

File diff suppressed because it is too large Load Diff

View File

@ -47,100 +47,101 @@ CODESEG=46
DATASEG=47
ENCODING=48
CONST=49
EXTERN=50
EXPORT=51
ALIGN=52
REGISTER=53
NOTREGISTER=54
ADDRESS=55
ADDRESS_ZEROPAGE=56
ADDRESS_MAINMEM=57
FORM_SSA=58
FORM_NOTSSA=59
INLINE=60
VOLATILE=61
NOTVOLATILE=62
INTERRUPT=63
CALLING=64
CALLINGCONVENTION=65
IF=66
ELSE=67
WHILE=68
DO=69
FOR=70
SWITCH=71
RETURN=72
BREAK=73
CONTINUE=74
ASM=75
DEFAULT=76
CASE=77
STRUCT=78
ENUM=79
SIZEOF=80
TYPEID=81
KICKASM=82
RESOURCE=83
USES=84
CLOBBERS=85
BYTES=86
CYCLES=87
LOGIC_NOT=88
SIGNEDNESS=89
SIMPLETYPE=90
BOOLEAN=91
KICKASM_BODY=92
STRING=93
CHAR=94
NUMBER=95
NUMFLOAT=96
BINFLOAT=97
DECFLOAT=98
HEXFLOAT=99
NUMINT=100
BININTEGER=101
DECINTEGER=102
HEXINTEGER=103
NAME=104
WS=105
COMMENT_LINE=106
COMMENT_BLOCK=107
ASM_BYTE=108
ASM_MNEMONIC=109
ASM_IMM=110
ASM_COLON=111
ASM_COMMA=112
ASM_PAR_BEGIN=113
ASM_PAR_END=114
ASM_BRACKET_BEGIN=115
ASM_BRACKET_END=116
ASM_DOT=117
ASM_SHIFT_LEFT=118
ASM_SHIFT_RIGHT=119
ASM_PLUS=120
ASM_MINUS=121
ASM_LESS_THAN=122
ASM_GREATER_THAN=123
ASM_MULTIPLY=124
ASM_DIVIDE=125
ASM_CURLY_BEGIN=126
ASM_CURLY_END=127
ASM_NUMBER=128
ASM_NUMFLOAT=129
ASM_BINFLOAT=130
ASM_DECFLOAT=131
ASM_HEXFLOAT=132
ASM_NUMINT=133
ASM_BININTEGER=134
ASM_DECINTEGER=135
ASM_HEXINTEGER=136
ASM_CHAR=137
ASM_MULTI_REL=138
ASM_MULTI_NAME=139
ASM_NAME=140
ASM_WS=141
ASM_COMMENT_LINE=142
ASM_COMMENT_BLOCK=143
NOTCONST=50
MAYBECONST=51
EXTERN=52
EXPORT=53
ALIGN=54
REGISTER=55
ADDRESS=56
ADDRESS_ZEROPAGE=57
ADDRESS_MAINMEM=58
FORM_SSA=59
FORM_NOTSSA=60
INLINE=61
VOLATILE=62
NOTVOLATILE=63
INTERRUPT=64
CALLING=65
CALLINGCONVENTION=66
IF=67
ELSE=68
WHILE=69
DO=70
FOR=71
SWITCH=72
RETURN=73
BREAK=74
CONTINUE=75
ASM=76
DEFAULT=77
CASE=78
STRUCT=79
ENUM=80
SIZEOF=81
TYPEID=82
KICKASM=83
RESOURCE=84
USES=85
CLOBBERS=86
BYTES=87
CYCLES=88
LOGIC_NOT=89
SIGNEDNESS=90
SIMPLETYPE=91
BOOLEAN=92
KICKASM_BODY=93
STRING=94
CHAR=95
NUMBER=96
NUMFLOAT=97
BINFLOAT=98
DECFLOAT=99
HEXFLOAT=100
NUMINT=101
BININTEGER=102
DECINTEGER=103
HEXINTEGER=104
NAME=105
WS=106
COMMENT_LINE=107
COMMENT_BLOCK=108
ASM_BYTE=109
ASM_MNEMONIC=110
ASM_IMM=111
ASM_COLON=112
ASM_COMMA=113
ASM_PAR_BEGIN=114
ASM_PAR_END=115
ASM_BRACKET_BEGIN=116
ASM_BRACKET_END=117
ASM_DOT=118
ASM_SHIFT_LEFT=119
ASM_SHIFT_RIGHT=120
ASM_PLUS=121
ASM_MINUS=122
ASM_LESS_THAN=123
ASM_GREATER_THAN=124
ASM_MULTIPLY=125
ASM_DIVIDE=126
ASM_CURLY_BEGIN=127
ASM_CURLY_END=128
ASM_NUMBER=129
ASM_NUMFLOAT=130
ASM_BINFLOAT=131
ASM_DECFLOAT=132
ASM_HEXFLOAT=133
ASM_NUMINT=134
ASM_BININTEGER=135
ASM_DECINTEGER=136
ASM_HEXINTEGER=137
ASM_CHAR=138
ASM_MULTI_REL=139
ASM_MULTI_NAME=140
ASM_NAME=141
ASM_WS=142
ASM_COMMENT_LINE=143
ASM_COMMENT_BLOCK=144
';'=8
'..'=11
'?'=12
@ -171,43 +172,44 @@ ASM_COMMENT_BLOCK=143
'data_seg'=47
'encoding'=48
'const'=49
'extern'=50
'export'=51
'align'=52
'register'=53
'__notregister'=54
'__address'=55
'__zp'=56
'__mem'=57
'__ssa'=58
'__notssa'=59
'inline'=60
'volatile'=61
'__notvolatile'=62
'interrupt'=63
'calling'=64
'if'=66
'else'=67
'while'=68
'do'=69
'for'=70
'switch'=71
'return'=72
'break'=73
'continue'=74
'asm'=75
'default'=76
'case'=77
'struct'=78
'enum'=79
'sizeof'=80
'typeid'=81
'kickasm'=82
'resource'=83
'uses'=84
'clobbers'=85
'bytes'=86
'cycles'=87
'!'=88
'.byte'=108
'#'=110
'__notconst'=50
'__maybeconst'=51
'extern'=52
'export'=53
'align'=54
'register'=55
'__address'=56
'__zp'=57
'__mem'=58
'__ssa'=59
'__notssa'=60
'inline'=61
'volatile'=62
'__notvolatile'=63
'interrupt'=64
'calling'=65
'if'=67
'else'=68
'while'=69
'do'=70
'for'=71
'switch'=72
'return'=73
'break'=74
'continue'=75
'asm'=76
'default'=77
'case'=78
'struct'=79
'enum'=80
'sizeof'=81
'typeid'=82
'kickasm'=83
'resource'=84
'uses'=85
'clobbers'=86
'bytes'=87
'cycles'=88
'!'=89
'.byte'=109
'#'=111

View File

@ -325,6 +325,30 @@ public class KickCParserBaseListener implements KickCParserListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveConst(KickCParser.DirectiveConstContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx) { }
/**
* {@inheritDoc}
*
@ -373,18 +397,6 @@ 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 enterDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -195,6 +195,20 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveConst(KickCParser.DirectiveConstContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@ -223,13 +237,6 @@ 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 visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -297,6 +297,30 @@ public interface KickCParserListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitDirectiveConst(KickCParser.DirectiveConstContext ctx);
/**
* Enter a parse tree produced by the {@code directiveNotConst}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx);
/**
* Exit a parse tree produced by the {@code directiveNotConst}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx);
/**
* Enter a parse tree produced by the {@code directiveMaybeConst}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx);
/**
* Exit a parse tree produced by the {@code directiveMaybeConst}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx);
/**
* Enter a parse tree produced by the {@code directiveExtern}
* labeled alternative in {@link KickCParser#directive}.
@ -345,18 +369,6 @@ public interface KickCParserListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx);
/**
* Enter a parse tree produced by the {@code directiveNotRegister}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
/**
* Exit a parse tree produced by the {@code directiveNotRegister}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
/**
* Enter a parse tree produced by the {@code directiveMemoryAreaZp}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -182,6 +182,20 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitDirectiveConst(KickCParser.DirectiveConstContext ctx);
/**
* Visit a parse tree produced by the {@code directiveNotConst}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx);
/**
* Visit a parse tree produced by the {@code directiveMaybeConst}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx);
/**
* Visit a parse tree produced by the {@code directiveExtern}
* labeled alternative in {@link KickCParser#directive}.
@ -210,13 +224,6 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx);
/**
* Visit a parse tree produced by the {@code directiveNotRegister}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
/**
* Visit a parse tree produced by the {@code directiveMemoryAreaZp}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -626,7 +626,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
addDirectives(lValue, false, directives, new StatementSource(ctx));
// Array / String variables are implicitly constant
if(type instanceof SymbolTypeArray || type.equals(SymbolType.STRING)) {
lValue.setDeclaredConstant(true);
lValue.setConstantDeclaration(SymbolVariable.ConstantDeclaration.CONST);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
lValue.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
}
@ -742,7 +742,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Directive visitDirectiveConst(KickCParser.DirectiveConstContext ctx) {
return new Directive.Const();
return new Directive.Const(SymbolVariable.ConstantDeclaration.CONST);
}
@Override
public Object visitDirectiveNotConst(KickCParser.DirectiveNotConstContext ctx) {
return new Directive.Const(SymbolVariable.ConstantDeclaration.NOT_CONST);
}
@Override
public Object visitDirectiveMaybeConst(KickCParser.DirectiveMaybeConstContext ctx) {
return new Directive.Const(SymbolVariable.ConstantDeclaration.MAYBE_CONST);
}
@Override
@ -784,11 +794,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return new Directive.Register(true, name);
}
@Override
public Object visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) {
return new Directive.Register(false, null);
}
@Override
public Object visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) {
return new Directive.MemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);

View File

@ -30,6 +30,9 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
for(Variable variable : getProgram().getScope().getAllVariables(true)) {
VariableRef variableRef = variable.getRef();
if(!variable.isDeclaredConstant() && !variable.isVolatile() && !variableRef.isIntermediate()) {
if(variable.isDeclaredNotConstant())
// Skip explicit non-constants
continue;
if(!isParameter(variableRef)) {
Collection<StatementLValue> assignments = getAssignments(variable);
if(assignments.size() == 1) {

View File

@ -303,7 +303,7 @@ public class Pass1ProcedureInline extends Pass1Base {
Variable inlineVar = callScope.addVariablePhiMaster(inlineVarName, procSymbol.getType(), procVar.getMemoryArea(), procVar.getDataSegment());
inlineVar.setInferredType(procVar.isInferredType());
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
inlineVar.setDeclaredConstant(procVar.isDeclaredConstant());
inlineVar.setConstantDeclaration(procVar.getConstantDeclaration());
inlineVar.setDeclaredAsRegister(procVar.isDeclaredAsRegister());
inlineVar.setDeclaredNotRegister(procVar.isDeclaredAsNotRegister());
inlineVar.setDeclaredRegister(procVar.getDeclaredRegister());

View File

@ -78,7 +78,7 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
Variable var = (Variable) symbol;
Variable unwound = procedure.addVariablePhiMaster(name, symbol.getType(), var.getMemoryArea(), var.getDataSegment());
unwound.setDeclaredAlignment(var.getDeclaredAlignment());
unwound.setDeclaredConstant(var.isDeclaredConstant());
unwound.setConstantDeclaration(var.getConstantDeclaration());
unwound.setDeclaredVolatile(var.isDeclaredVolatile());
unwound.setInferedVolatile(var.isInferedVolatile());
unwound.setDeclaredRegister((var.getDeclaredRegister()));

View File

@ -223,7 +223,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
}
memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile());
memberVariable.setInferedVolatile(variable.isInferedVolatile());
memberVariable.setDeclaredConstant(variable.isDeclaredConstant());
memberVariable.setConstantDeclaration(variable.getConstantDeclaration());
memberVariable.setDeclaredExport(variable.isDeclaredExport());
memberVariable.setStorageStrategy(variable.getStorageStrategy());
if(memberVariable.getType() instanceof SymbolTypePointer) {

View File

@ -93,7 +93,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
String unversionedFullName = null;
for(VariableRef variableRef : aliasSet.getVars()) {
Variable variable = programScope.getVariable(variableRef);
if(variable.isVolatile()) {
if(variable.isVolatile() || variable.isStorageLoadStore()) {
anyVolatile = true;
}
if(unversionedFullName == null) {

View File

@ -10,17 +10,18 @@ import dk.camelot64.kickc.model.operators.OperatorUnary;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementLValue;
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.values.*;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* Compiler Pass propagating constants in expressions eliminating constant variables
@ -155,11 +156,11 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
if(lValue instanceof VariableRef) {
VariableRef varRef = (VariableRef) lValue;
Variable var = getScope().getVariable(varRef);
if(var.isVolatile() || var.isStorageLoadStore())
if(var.isVolatile() || var.isDeclaredNotConstant() || var.isStorageLoadStore())
// Do not examine volatiles and non-versioned variables
continue;
ConstantValue constant = getConstant(assignment.getrValue2());
if(assignment.getrValue1() == null && assignment.getOperator() == null && constant !=null) {
if(assignment.getrValue1() == null && assignment.getOperator() == null && constant != null) {
constants.put(varRef, new ConstantVariableValue(varRef, constant, assignment));
}
}
@ -171,7 +172,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
if(getConstant(phiRValue.getrValue()) != null) {
VariableRef varRef = phiVariable.getVariable();
Variable var = getScope().getVariable(varRef);
if(var.isVolatile() || var.isStorageLoadStore())
if(var.isVolatile() || var.isDeclaredNotConstant() || var.isStorageLoadStore())
// Do not examine volatiles and non-versioned variables
continue;
ConstantValue constant = getConstant(phiRValue.getrValue());
@ -184,6 +185,29 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
}
// Look for constants among non-versioned variables
for(Variable variable : getScope().getAllVariables(true)) {
if(variable.isVolatile() || variable.isDeclaredNotConstant() || !variable.isStorageLoadStore())
// Do not examine volatiles, non-constants or versioned variables
continue;
List<StatementLValue> assignments = getGraph().getAssignments(variable.getRef());
if(assignments.size() == 1) {
StatementLValue statementLValue = assignments.get(0);
if(!(statementLValue instanceof StatementAssignment))
// Only look at assignments
continue;
StatementAssignment assignment = (StatementAssignment) statementLValue;
LValue lValue = assignment.getlValue();
if(lValue instanceof VariableRef) {
VariableRef varRef = (VariableRef) lValue;
ConstantValue constant = getConstant(assignment.getrValue2());
if(assignment.getrValue1() == null && assignment.getOperator() == null && constant != null) {
constants.put(varRef, new ConstantVariableValue(varRef, constant, assignment));
throw new CompileError("Encountered constant variable! " + variable.toString(), statementLValue);
}
}
}
}
return constants;
}

View File

@ -135,11 +135,11 @@ public class PassNTypeInference extends Pass2SsaOptimization {
setInferedType(program, assignment, symbol, type);
// If the type is an array or a string the symbol is constant
if(symbol.getType() instanceof SymbolTypeArray) {
symbol.setDeclaredConstant(true);
symbol.setConstantDeclaration(SymbolVariable.ConstantDeclaration.CONST);
symbol.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
symbol.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
} else if(SymbolType.STRING.equals(symbol.getType())) {
symbol.setDeclaredConstant(true);
symbol.setConstantDeclaration(SymbolVariable.ConstantDeclaration.CONST);
symbol.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
symbol.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
}

View File

@ -1,6 +1,6 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
__notregister __mem char idx;
__mem __notssa char idx;
const char* SCREEN = 0x0400;

View File

@ -1,7 +1,7 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a pointer to a memory variable
__notregister __mem char idx;
__mem __notssa char idx;
char* idx_p = &idx;
const char* SCREEN = 0x0400;

View File

@ -3,7 +3,7 @@
const char* SCREEN = 0x0400;
__notregister __mem char* cursor = SCREEN;
__mem __notssa char* cursor = SCREEN;
void main() {
for( char i: 0..24 ) {

View File

@ -6,7 +6,7 @@ struct foo {
char thing2;
};
__notregister __mem struct foo bar = { 'a', 'b' };
__mem __notssa struct foo bar = { 'a', 'b' };
void main(void) {
struct foo* barp = &bar;

View File

@ -7,7 +7,7 @@ struct foo {
char[12] thing3;
};
__notregister __mem struct foo bar = { 'a', 'b', "qwe" };
__mem __notssa struct foo bar = { 'a', 'b', "qwe" };
void main(void) {
struct foo* barp = &bar;

View File

@ -6,7 +6,7 @@ struct foo {
char thing2;
};
__notregister __mem struct foo bar = { 'a', 'b' };
__mem __notssa __notconst struct foo bar = { 'a', 'b' };
void main(void) {
const char* SCREEN = 0x0400;

View File

@ -5,19 +5,19 @@ char i=0;
void main(void) {
char register __zp reg_zp_flex = '.';
char register __address(0x10) reg_zp_abs = '.';
char register __mem reg_mem_flex = '.';
char register __address(0x1000) reg_mem_abs = '.';
char __notregister __zp notreg_zp_flex = '.';
char __notregister __address(0x10) notreg_zp_abs = '.';
char __notregister __mem notreg_mem_flex = '.';
char __notregister __address(0x1000) notreg_mem_abs = '.';
char __ssa __zp reg_zp_flex = '.';
char __ssa __address(0x10) reg_zp_abs = '.';
char __ssa __mem reg_mem_flex = '.';
char __ssa __address(0x1000) reg_mem_abs = '.';
char __notssa __notconst __zp notreg_zp_flex = '.';
char __notssa __notconst __address(0x10) notreg_zp_abs = '.';
char __notssa __notconst __mem notreg_mem_flex = '.';
char __notssa __notconst __address(0x1000) notreg_mem_abs = '.';
char default_default = '.';
char register reg_default = '.';
char __notregister notreg_default = '.';
char __zp default_zp_flex = '.';
char reg_default = '.';
char __notssa __notconst notreg_default = '.';
char __ssa __zp default_zp_flex = '.';
char __address(0x10) default_zp_abs = '.';
char __mem default_mem_flex = '.';
char __address(0x1000) default_mem_abs = '.';

View File

@ -1,7 +1,7 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a zeropage notregister variable
__notregister char idx;
__notssa char idx;
const char* SCREEN = 0x0400;

View File

@ -1,7 +1,7 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a fixed main memory address notregister variable
// Test declaring a variable as "memory", meaning it will be stored in main memory
// Test a fixed main memory address __notssa variable
__notregister __address(0x1000) char idx;
__notssa __address(0x1000) char idx;
const char* SCREEN = 0x0400;

View File

@ -1,4 +1,4 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"

View File

@ -127,7 +127,7 @@ Allocated mem[1] [ idx ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
@ -214,7 +214,7 @@ Uplifting [] best 409 combination mem[1] [ idx ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
@ -318,7 +318,7 @@ FINAL ASSEMBLER
Score: 319
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)

View File

@ -1,5 +1,5 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a fixed main memory address notregister variable
// Test declaring a variable as "memory", meaning it will be stored in main memory
// Test a fixed main memory address __notssa variable
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"

View File

@ -126,8 +126,8 @@ Allocated zp[1]:2 [ main::i#2 main::i#1 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a fixed main memory address notregister variable
// Test declaring a variable as "memory", meaning it will be stored in main memory
// Test a fixed main memory address __notssa variable
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
@ -214,8 +214,8 @@ Uplifting [] best 409 combination mem[1]:4096 [ idx ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a fixed main memory address notregister variable
// Test declaring a variable as "memory", meaning it will be stored in main memory
// Test a fixed main memory address __notssa variable
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
@ -319,8 +319,8 @@ FINAL ASSEMBLER
Score: 319
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a fixed main memory address notregister variable
// Test declaring a variable as "memory", meaning it will be stored in main memory
// Test a fixed main memory address __notssa variable
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)