mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-26 18:29:54 +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
|
||||||
: PRAGMA NAME
|
: PRAGMA NAME PAR_BEGIN PAR_END #pragmaNoParameters
|
||||||
| PRAGMA NAME (PAR_BEGIN pragmaParam (COMMA pragmaParam)* PAR_END)?
|
| PRAGMA NAME PAR_BEGIN pragmaParam (COMMA pragmaParam)* PAR_END #pragmaParameters
|
||||||
;
|
;
|
||||||
|
|
||||||
pragmaParam
|
pragmaParam
|
||||||
|
@ -42,7 +42,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
/** Used to build the scopes of the source file. */
|
/** Used to build the scopes of the source file. */
|
||||||
private final Stack<Scope> scopeStack;
|
private final Stack<Scope> scopeStack;
|
||||||
/** All #pragma constructor_for() statements. Collected during parsing and handled by {@link #generate()} before returning. */
|
/** 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) {
|
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()
|
// Handle #pragma constructor_for()
|
||||||
List<ProcedureRef> constructorProcs = new ArrayList<>();
|
List<ProcedureRef> constructorProcs = new ArrayList<>();
|
||||||
for(KickCParser.PragmaContext pragmaConstructorFor : pragmaConstructorFors) {
|
for(KickCParser.PragmaParametersContext pragmaConstructorFor : pragmaConstructorFors) {
|
||||||
final List<KickCParser.PragmaParamContext> names = pragmaConstructorFor.pragmaParam();
|
final List<KickCParser.PragmaParamContext> names = pragmaConstructorFor.pragmaParam();
|
||||||
if(names.size() < 2)
|
if(names.size() < 2)
|
||||||
throw new CompileError("#pragma constructor_for requires at least 2 parameters.", new StatementSource(pragmaConstructorFor));
|
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;
|
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
|
@Override
|
||||||
public Object visitPragma(KickCParser.PragmaContext ctx) {
|
public Object visitPragmaParameters(KickCParser.PragmaParametersContext ctx) {
|
||||||
final String pragmaName = ctx.NAME().getText();
|
final String pragmaName = ctx.NAME().getText();
|
||||||
switch(pragmaName) {
|
switch(pragmaName) {
|
||||||
case CParser.PRAGMA_TARGET:
|
case CParser.PRAGMA_TARGET:
|
||||||
@ -340,7 +361,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
* @param ctx The #pragma
|
* @param ctx The #pragma
|
||||||
* @return The single parameter
|
* @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)
|
if(ctx.pragmaParam().size() != 1)
|
||||||
throw new CompileError("#pragma expects a single parameter!", new StatementSource(ctx));
|
throw new CompileError("#pragma expects a single parameter!", new StatementSource(ctx));
|
||||||
return ctx.pragmaParam().get(0);
|
return ctx.pragmaParam().get(0);
|
||||||
|
@ -245,6 +245,14 @@ public class CPreprocessor implements TokenSource {
|
|||||||
pragmaTokens.addAll(pragmaBody);
|
pragmaTokens.addAll(pragmaBody);
|
||||||
// Pass on the #pragma to the parser - and mark it as already handled
|
// Pass on the #pragma to the parser - and mark it as already handled
|
||||||
cTokenSource.addSourceFirst(new ListTokenSource(pragmaTokens));
|
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);
|
parserPragmas.add(inputToken);
|
||||||
return true;
|
return true;
|
||||||
|
@ -30,10 +30,6 @@
|
|||||||
|
|
||||||
char* const SCREEN = (char*)0x0400;
|
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 code_seg(RAM_Bank1)
|
||||||
#pragma bank(cx16_ram, 1)
|
#pragma bank(cx16_ram, 1)
|
||||||
@ -47,4 +43,8 @@ char min(char a, char b) {
|
|||||||
return a+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
|
[6] return
|
||||||
to:@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: scope:[min] from plus
|
||||||
[7] phi()
|
[7] phi()
|
||||||
to:min::@return
|
to:min::@return
|
||||||
|
@ -2,22 +2,6 @@ Loading link script "call-banked-phi.ld"
|
|||||||
|
|
||||||
CONTROL FLOW GRAPH SSA
|
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)
|
__bank(cx16_ram, 1) char plus(char a , char b)
|
||||||
plus: scope:[plus] from main
|
plus: scope:[plus] from main
|
||||||
plus::b#1 = phi( main/plus::b#0 )
|
plus::b#1 = phi( main/plus::b#0 )
|
||||||
@ -30,15 +14,15 @@ plus: scope:[plus] from main
|
|||||||
plus::@1: scope:[plus] from plus
|
plus::@1: scope:[plus] from plus
|
||||||
min::return#3 = phi( plus/min::return#0 )
|
min::return#3 = phi( plus/min::return#0 )
|
||||||
plus::$0 = min::return#3
|
plus::$0 = min::return#3
|
||||||
plus::return#1 = plus::$0
|
plus::return#0 = plus::$0
|
||||||
to:plus::@return
|
to:plus::@return
|
||||||
plus::@return: scope:[plus] from plus::@1
|
plus::@return: scope:[plus] from plus::@1
|
||||||
plus::return#4 = phi( plus::@1/plus::return#1 )
|
plus::return#3 = phi( plus::@1/plus::return#0 )
|
||||||
plus::return#2 = plus::return#4
|
plus::return#1 = plus::return#3
|
||||||
return
|
return
|
||||||
to:@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: scope:[min] from plus
|
||||||
min::b#1 = phi( plus/min::b#0 )
|
min::b#1 = phi( plus/min::b#0 )
|
||||||
min::a#1 = phi( plus/min::a#0 )
|
min::a#1 = phi( plus/min::a#0 )
|
||||||
@ -51,6 +35,22 @@ min::@return: scope:[min] from min
|
|||||||
return
|
return
|
||||||
to:@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()
|
void __start()
|
||||||
__start: scope:[__start] from
|
__start: scope:[__start] from
|
||||||
call main
|
call main
|
||||||
@ -66,7 +66,7 @@ __constant char * const SCREEN = (char *)$400
|
|||||||
void __start()
|
void __start()
|
||||||
void main()
|
void main()
|
||||||
char main::$0
|
char main::$0
|
||||||
__bank(cx16_ram, 1) char min(char a , char b)
|
char min(char a , char b)
|
||||||
char min::$0
|
char min::$0
|
||||||
char min::a
|
char min::a
|
||||||
char min::a#0
|
char min::a#0
|
||||||
@ -107,10 +107,10 @@ Successful SSA optimization PassNCastSimplification
|
|||||||
Finalized unsigned number type (char) 7
|
Finalized unsigned number type (char) 7
|
||||||
Finalized unsigned number type (char) 0
|
Finalized unsigned number type (char) 0
|
||||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
Alias plus::return#0 = plus::return#3
|
|
||||||
Alias min::return#0 = min::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 min::return#1 = min::$0 min::return#4 min::return#2
|
||||||
|
Alias plus::return#2 = plus::return#4
|
||||||
Successful SSA optimization Pass2AliasElimination
|
Successful SSA optimization Pass2AliasElimination
|
||||||
Identical Phi Values plus::a#1 plus::a#0
|
Identical Phi Values plus::a#1 plus::a#0
|
||||||
Identical Phi Values plus::b#1 plus::b#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::a#0 = plus::a#0
|
||||||
Constant min::b#0 = plus::b#0
|
Constant min::b#0 = plus::b#0
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
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
|
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||||
Removing unused procedure __start
|
Removing unused procedure __start
|
||||||
Removing unused procedure block __start
|
Removing unused procedure block __start
|
||||||
Removing unused procedure block __start::@1
|
Removing unused procedure block __start::@1
|
||||||
Removing unused procedure block __start::@return
|
Removing unused procedure block __start::@return
|
||||||
Successful SSA optimization PassNEliminateEmptyStart
|
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
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||||
Constant min::return#1 = min::a#0+min::b#0
|
Constant min::return#1 = min::a#0+min::b#0
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Constant min::return#0 = min::return#1
|
Constant min::return#0 = min::return#1
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Constant plus::return#1 = min::return#0
|
Constant plus::return#0 = min::return#0
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Constant plus::return#0 = plus::return#1
|
Constant plus::return#2 = plus::return#0
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Constant main::$0 = plus::return#0
|
Constant main::$0 = plus::return#2
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Inlining constant with different constant siblings min::return#0
|
Inlining constant with different constant siblings min::return#0
|
||||||
Constant inlined plus::return#0 = min::return#1
|
Constant inlined plus::return#0 = min::return#1
|
||||||
Constant inlined main::$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::a#0 = plus::a#0
|
||||||
Constant inlined min::return#0 = min::return#1
|
Constant inlined min::return#0 = min::return#1
|
||||||
|
Constant inlined plus::return#2 = min::return#1
|
||||||
Constant inlined min::b#0 = plus::b#0
|
Constant inlined min::b#0 = plus::b#0
|
||||||
Successful SSA optimization Pass2ConstantInlining
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
Adding NOP phi() at start of main
|
Adding NOP phi() at start of main
|
||||||
@ -188,7 +188,7 @@ plus::@return: scope:[plus] from plus
|
|||||||
[6] return
|
[6] return
|
||||||
to:@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: scope:[min] from plus
|
||||||
[7] phi()
|
[7] phi()
|
||||||
to:min::@return
|
to:min::@return
|
||||||
@ -199,7 +199,7 @@ min::@return: scope:[min] from min
|
|||||||
|
|
||||||
VARIABLE REGISTER WEIGHTS
|
VARIABLE REGISTER WEIGHTS
|
||||||
void main()
|
void main()
|
||||||
__bank(cx16_ram, 1) char min(char a , char b)
|
char min(char a , char b)
|
||||||
char min::a
|
char min::a
|
||||||
char min::b
|
char min::b
|
||||||
char min::return
|
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
|
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
|
||||||
REGISTER UPLIFT SCOPES
|
REGISTER UPLIFT SCOPES
|
||||||
Uplift Scope [main]
|
|
||||||
Uplift Scope [plus]
|
Uplift Scope [plus]
|
||||||
Uplift Scope [min]
|
Uplift Scope [min]
|
||||||
|
Uplift Scope [main]
|
||||||
Uplift Scope []
|
Uplift Scope []
|
||||||
|
|
||||||
Uplifting [main] best 90 combination
|
|
||||||
Uplifting [plus] best 90 combination
|
Uplifting [plus] best 90 combination
|
||||||
Uplifting [min] best 90 combination
|
Uplifting [min] best 90 combination
|
||||||
|
Uplifting [main] best 90 combination
|
||||||
Uplifting [] best 90 combination
|
Uplifting [] best 90 combination
|
||||||
|
|
||||||
ASSEMBLER BEFORE OPTIMIZATION
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
@ -341,7 +341,7 @@ Succesful ASM optimization Pass5UnusedLabelElimination
|
|||||||
FINAL SYMBOL TABLE
|
FINAL SYMBOL TABLE
|
||||||
__constant char * const SCREEN = (char *) 1024
|
__constant char * const SCREEN = (char *) 1024
|
||||||
void main()
|
void main()
|
||||||
__bank(cx16_ram, 1) char min(char a , char b)
|
char min(char a , char b)
|
||||||
char min::a
|
char min::a
|
||||||
char min::b
|
char min::b
|
||||||
char min::return
|
char min::return
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
__constant char * const SCREEN = (char *) 1024
|
__constant char * const SCREEN = (char *) 1024
|
||||||
void main()
|
void main()
|
||||||
__bank(cx16_ram, 1) char min(char a , char b)
|
char min(char a , char b)
|
||||||
char min::a
|
char min::a
|
||||||
char min::b
|
char min::b
|
||||||
char min::return
|
char min::return
|
||||||
|
Loading…
Reference in New Issue
Block a user