mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-26 03:32:23 +00:00
- Resolved issue of nobank without parameters. Now it works ... The CPreprocessor adds () and the KickCParser.g4 demands brackets as part of the syntax. But you can write without in the code.
- Retested all test cases.
This commit is contained in:
parent
5c5ffd2736
commit
82a6c56e0a
@ -136,8 +136,8 @@ parameterDecl
|
||||
;
|
||||
|
||||
pragma
|
||||
: PRAGMA NAME
|
||||
| PRAGMA NAME (PAR_BEGIN pragmaParam (COMMA pragmaParam)* PAR_END)?
|
||||
: PRAGMA NAME PAR_BEGIN PAR_END #pragmaNoParameters
|
||||
| PRAGMA NAME PAR_BEGIN pragmaParam (COMMA pragmaParam)* PAR_END #pragmaParameters
|
||||
;
|
||||
|
||||
pragmaParam
|
||||
|
@ -42,7 +42,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
/** Used to build the scopes of the source file. */
|
||||
private final Stack<Scope> scopeStack;
|
||||
/** All #pragma constructor_for() statements. Collected during parsing and handled by {@link #generate()} before returning. */
|
||||
private final List<KickCParser.PragmaContext> pragmaConstructorFors;
|
||||
private final List<KickCParser.PragmaParametersContext> pragmaConstructorFors;
|
||||
|
||||
|
||||
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, Procedure.CallingConvention initialCallingConvention, StringEncoding defaultEncoding, String defaultInterruptType) {
|
||||
@ -148,7 +148,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
// Handle #pragma constructor_for()
|
||||
List<ProcedureRef> constructorProcs = new ArrayList<>();
|
||||
for(KickCParser.PragmaContext pragmaConstructorFor : pragmaConstructorFors) {
|
||||
for(KickCParser.PragmaParametersContext pragmaConstructorFor : pragmaConstructorFors) {
|
||||
final List<KickCParser.PragmaParamContext> names = pragmaConstructorFor.pragmaParam();
|
||||
if(names.size() < 2)
|
||||
throw new CompileError("#pragma constructor_for requires at least 2 parameters.", new StatementSource(pragmaConstructorFor));
|
||||
@ -237,8 +237,29 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return null;
|
||||
}
|
||||
|
||||
// #pragma NAME without parameters are registered in the parser as #pragma NAME ().
|
||||
// The CPreprocessor.java parses first the #pragma statements and modifies them
|
||||
// and selects which pragmas are allowed to be passed to the main parser.
|
||||
// #pragma nobank is such a pragma, that must be passed. The CPreprocessor adds
|
||||
// parentheses after the NAME, which comply with the KickCParser.g4 definition.
|
||||
// But the programmer can write #pragma nobank without issues.
|
||||
public Object visitPragmaNoParameters(KickCParser.PragmaNoParametersContext ctx) {
|
||||
final String pragmaName = ctx.NAME().getText();
|
||||
switch(pragmaName) {
|
||||
case CParser.PRAGMA_TARGET:
|
||||
throw new InternalError("Error! #pragma target() should be handled in preprocessor!");
|
||||
case CParser.PRAGMA_NOBANK:
|
||||
this.currentBank = null; // When the current segment is null, the procedure will not be declared as far.
|
||||
break;
|
||||
default:
|
||||
program.getLog().append("Warning! Unknown #pragma " + pragmaName);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitPragma(KickCParser.PragmaContext ctx) {
|
||||
public Object visitPragmaParameters(KickCParser.PragmaParametersContext ctx) {
|
||||
final String pragmaName = ctx.NAME().getText();
|
||||
switch(pragmaName) {
|
||||
case CParser.PRAGMA_TARGET:
|
||||
@ -340,7 +361,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
* @param ctx The #pragma
|
||||
* @return The single parameter
|
||||
*/
|
||||
private static KickCParser.PragmaParamContext pragmaParamSingle(KickCParser.PragmaContext ctx) {
|
||||
private static KickCParser.PragmaParamContext pragmaParamSingle(KickCParser.PragmaParametersContext ctx) {
|
||||
if(ctx.pragmaParam().size() != 1)
|
||||
throw new CompileError("#pragma expects a single parameter!", new StatementSource(ctx));
|
||||
return ctx.pragmaParam().get(0);
|
||||
|
@ -245,6 +245,14 @@ public class CPreprocessor implements TokenSource {
|
||||
pragmaTokens.addAll(pragmaBody);
|
||||
// Pass on the #pragma to the parser - and mark it as already handled
|
||||
cTokenSource.addSourceFirst(new ListTokenSource(pragmaTokens));
|
||||
} else {
|
||||
ArrayList<Token> parenthesizedBody = new ArrayList<>();
|
||||
parenthesizedBody.add(new CommonToken(KickCLexer.PAR_BEGIN, "("));
|
||||
parenthesizedBody.add(new CommonToken(KickCLexer.PAR_END, ")"));
|
||||
pragmaBody = parenthesizedBody;
|
||||
pragmaTokens.addAll(pragmaBody);
|
||||
// Pass on the #pragma to the parser - and mark it as already handled
|
||||
cTokenSource.addSourceFirst(new ListTokenSource(pragmaTokens));
|
||||
}
|
||||
parserPragmas.add(inputToken);
|
||||
return true;
|
||||
|
@ -30,10 +30,6 @@
|
||||
|
||||
char* const SCREEN = (char*)0x0400;
|
||||
|
||||
#pragma code_seg(Code)
|
||||
void main(void) {
|
||||
SCREEN[0] = plus('0', 7); // close call
|
||||
}
|
||||
|
||||
#pragma code_seg(RAM_Bank1)
|
||||
#pragma bank(cx16_ram, 1)
|
||||
@ -47,4 +43,8 @@ char min(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
#pragma code_seg(Code)
|
||||
void main(void) {
|
||||
SCREEN[0] = plus('0', 7); // close call
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ plus::@return: scope:[plus] from plus
|
||||
[6] return
|
||||
to:@return
|
||||
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
min: scope:[min] from plus
|
||||
[7] phi()
|
||||
to:min::@return
|
||||
|
@ -2,22 +2,6 @@ Loading link script "call-banked-phi.ld"
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
plus::a#0 = '0'
|
||||
plus::b#0 = 7
|
||||
call plus
|
||||
plus::return#0 = plus::return#2
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
plus::return#3 = phi( main/plus::return#0 )
|
||||
main::$0 = plus::return#3
|
||||
SCREEN[0] = main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
__bank(cx16_ram, 1) char plus(char a , char b)
|
||||
plus: scope:[plus] from main
|
||||
plus::b#1 = phi( main/plus::b#0 )
|
||||
@ -30,15 +14,15 @@ plus: scope:[plus] from main
|
||||
plus::@1: scope:[plus] from plus
|
||||
min::return#3 = phi( plus/min::return#0 )
|
||||
plus::$0 = min::return#3
|
||||
plus::return#1 = plus::$0
|
||||
plus::return#0 = plus::$0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus::@1
|
||||
plus::return#4 = phi( plus::@1/plus::return#1 )
|
||||
plus::return#2 = plus::return#4
|
||||
plus::return#3 = phi( plus::@1/plus::return#0 )
|
||||
plus::return#1 = plus::return#3
|
||||
return
|
||||
to:@return
|
||||
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
min: scope:[min] from plus
|
||||
min::b#1 = phi( plus/min::b#0 )
|
||||
min::a#1 = phi( plus/min::a#0 )
|
||||
@ -51,6 +35,22 @@ min::@return: scope:[min] from min
|
||||
return
|
||||
to:@return
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
plus::a#0 = '0'
|
||||
plus::b#0 = 7
|
||||
call plus
|
||||
plus::return#2 = plus::return#1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
plus::return#4 = phi( main/plus::return#2 )
|
||||
main::$0 = plus::return#4
|
||||
SCREEN[0] = main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
@ -66,7 +66,7 @@ __constant char * const SCREEN = (char *)$400
|
||||
void __start()
|
||||
void main()
|
||||
char main::$0
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
char min::$0
|
||||
char min::a
|
||||
char min::a#0
|
||||
@ -107,10 +107,10 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (char) 7
|
||||
Finalized unsigned number type (char) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias plus::return#0 = plus::return#3
|
||||
Alias min::return#0 = min::return#3
|
||||
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
|
||||
Alias plus::return#0 = plus::$0 plus::return#3 plus::return#1
|
||||
Alias min::return#1 = min::$0 min::return#4 min::return#2
|
||||
Alias plus::return#2 = plus::return#4
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Identical Phi Values plus::a#1 plus::a#0
|
||||
Identical Phi Values plus::b#1 plus::b#0
|
||||
@ -123,31 +123,31 @@ Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant min::a#0 = plus::a#0
|
||||
Constant min::b#0 = plus::b#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
|
||||
Simplifying expression containing zero SCREEN in [15] SCREEN[0] = main::$0
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Removing unused procedure __start
|
||||
Removing unused procedure block __start
|
||||
Removing unused procedure block __start::@1
|
||||
Removing unused procedure block __start::@return
|
||||
Successful SSA optimization PassNEliminateEmptyStart
|
||||
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
|
||||
Constant right-side identified [4] min::return#1 = min::a#0 + min::b#0
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant min::return#1 = min::a#0+min::b#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant min::return#0 = min::return#1
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant plus::return#1 = min::return#0
|
||||
Constant plus::return#0 = min::return#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant plus::return#0 = plus::return#1
|
||||
Constant plus::return#2 = plus::return#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant main::$0 = plus::return#0
|
||||
Constant main::$0 = plus::return#2
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Inlining constant with different constant siblings min::return#0
|
||||
Constant inlined plus::return#0 = min::return#1
|
||||
Constant inlined main::$0 = min::return#1
|
||||
Constant inlined plus::return#1 = min::return#1
|
||||
Constant inlined min::a#0 = plus::a#0
|
||||
Constant inlined min::return#0 = min::return#1
|
||||
Constant inlined plus::return#2 = min::return#1
|
||||
Constant inlined min::b#0 = plus::b#0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Adding NOP phi() at start of main
|
||||
@ -188,7 +188,7 @@ plus::@return: scope:[plus] from plus
|
||||
[6] return
|
||||
to:@return
|
||||
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
min: scope:[min] from plus
|
||||
[7] phi()
|
||||
to:min::@return
|
||||
@ -199,7 +199,7 @@ min::@return: scope:[min] from min
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
void main()
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
char min::a
|
||||
char min::b
|
||||
char min::return
|
||||
@ -215,14 +215,14 @@ Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope [plus]
|
||||
Uplift Scope [min]
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 90 combination
|
||||
Uplifting [plus] best 90 combination
|
||||
Uplifting [min] best 90 combination
|
||||
Uplifting [main] best 90 combination
|
||||
Uplifting [] best 90 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
@ -341,7 +341,7 @@ Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
FINAL SYMBOL TABLE
|
||||
__constant char * const SCREEN = (char *) 1024
|
||||
void main()
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
char min::a
|
||||
char min::b
|
||||
char min::return
|
||||
|
@ -1,6 +1,6 @@
|
||||
__constant char * const SCREEN = (char *) 1024
|
||||
void main()
|
||||
__bank(cx16_ram, 1) char min(char a , char b)
|
||||
char min(char a , char b)
|
||||
char min::a
|
||||
char min::b
|
||||
char min::return
|
||||
|
Loading…
Reference in New Issue
Block a user