1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-28 01:29:44 +00:00

added support for expressions in __address

This commit is contained in:
Andrzej Sliwa 2020-12-09 12:18:07 +01:00
parent 49b58cc610
commit e8155008a2
18 changed files with 2186 additions and 580 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.values.ConstantValue;
import java.util.List;

View File

@ -47,7 +47,7 @@ public class RegisterUpliftScope {
}
out.append(equivalenceClass.toString() + " ");
}
return out.toString();
return out.toString().trim();
}
@Override

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCLexer.g4 by ANTLR 4.8
// Generated from /Users/andrzejsliwa/kickc/src/main/java/dk/camelot64/kickc/parser/KickCLexer.g4 by ANTLR 4.9
package dk.camelot64.kickc.parser;
@ -13,7 +13,7 @@ import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class KickCLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); }
static { RuntimeMetaData.checkVersion("4.9", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =

View File

@ -151,7 +151,7 @@ directive
| REGISTER ( PAR_BEGIN ( NAME ) PAR_END)? #directiveRegister
| ADDRESS_ZEROPAGE #directiveMemoryAreaZp
| ADDRESS_MAINMEM #directiveMemoryAreaMain
| ADDRESS PAR_BEGIN ( NUMBER ) PAR_END #directiveMemoryAreaAddress
| ADDRESS PAR_BEGIN ( expr ) PAR_END #directiveMemoryAreaAddress
| VOLATILE #directiveVolatile
| STATIC #directiveStatic
| FORM_SSA #directiveFormSsa

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.8
// Generated from /Users/andrzejsliwa/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
package dk.camelot64.kickc.parser;

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.8
// Generated from /Users/andrzejsliwa/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
package dk.camelot64.kickc.parser;

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.8
// Generated from /Users/andrzejsliwa/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
package dk.camelot64.kickc.parser;

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.8
// Generated from /Users/andrzejsliwa/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
package dk.camelot64.kickc.parser;

View File

@ -1261,9 +1261,18 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Directive visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) {
try {
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
Long address = memoryAddress.getInteger();
return new Directive.Address(address);
KickCParser.ExprContext initializer = ctx.expr();
RValue initValue = (initializer == null) ? null : (RValue) visit(initializer);
StatementSource statementSource = new StatementSource(ctx);
ConstantValue addressAsConstantValue = getConstInitValue(initValue, initializer, statementSource);
ConstantLiteral literal = addressAsConstantValue.calculateLiteral(program.getScope());
if(literal instanceof ConstantInteger) {
Long address = ((ConstantInteger) literal).getValue();
return new Directive.Address(address);
} else {
throw new CompileError("__address is not an integer :" + initValue.toString(program), new StatementSource(ctx));
}
} catch(NumberFormatException e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx));
}

View File

@ -1064,6 +1064,11 @@ public class TestPrograms {
compileAndCompare("address-9.c");
}
@Test
public void testAddressWithExpressionValue() throws IOException, URISyntaxException {
compileAndCompare("address-with-expression-value.c", log());
}
@Test
public void testAddress8() throws IOException, URISyntaxException {
compileAndCompare("address-8.c");
@ -5056,8 +5061,8 @@ public class TestPrograms {
success &= helper.testOutput(baseFileName, ".cfg", program.getGraph().toString(program));
success &= helper.testOutput(baseFileName, ".log", program.getLog().toString());
if(!success) {
//System.out.println("\nCOMPILE LOG");
//System.out.println(program.getLog().toString());
// System.out.println("\nCOMPILE LOG");
// System.out.println(program.getLog().toString());
fail("Output does not match reference!");
}
// Save the ASM fragment caches (if there are any changes)

View File

@ -0,0 +1,16 @@
// Test declaring an address as expression
// The screen
char * const SCREEN = 0x0400;
word const var1 = 0x800;
word const var2 = 0x900;
// Data to be put on the screen
char __address(var1 + var2) DATA[1000];
void main() {
SCREEN[0] = DATA[0];
}

View File

@ -0,0 +1,17 @@
// Test declaring an address as expression
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// The screen
.label SCREEN = $400
main: {
// SCREEN[0] = DATA[0]
lda DATA
sta SCREEN
// }
rts
}
.pc = $1100 "DATA"
// Data to be put on the screen
DATA: .fill $3e8, 0

View File

@ -0,0 +1,9 @@
void main()
main: scope:[main] from
[0] *SCREEN = *DATA
to:main::@return
main::@return: scope:[main] from main
[1] return
to:@return

View File

@ -0,0 +1,143 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
SCREEN[0] = DATA[0]
to:main::@return
main::@return: scope:[main] from main
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
const byte* DATA[$3e8] = { fill( $3e8, 0) }
const nomodify byte* SCREEN = (byte*)$400
void __start()
void main()
Adding number conversion cast (unumber) 0 in SCREEN[0] = DATA[0]
Adding number conversion cast (unumber) 0 in SCREEN[0] = DATA[(unumber)0]
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 0
Finalized unsigned number type 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero DATA in [0] SCREEN[0] = DATA[0]
Simplifying expression containing zero SCREEN in [0] SCREEN[0] = *DATA
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
CALL GRAPH
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *SCREEN = *DATA
to:main::@return
main::@return: scope:[main] from main
[1] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *SCREEN = *DATA [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 17 combination
Uplifting [] best 17 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test declaring an address as expression
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// The screen
.label SCREEN = $400
// main
main: {
// [0] *SCREEN = *DATA -- _deref_pbuc1=_deref_pbuc2
lda DATA
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [1] return
rts
}
// File Data
.pc = $1100 "DATA"
// Data to be put on the screen
DATA: .fill $3e8, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const byte* DATA[$3e8] = { fill( $3e8, 0) }
const nomodify byte* SCREEN = (byte*) 1024
void main()
FINAL ASSEMBLER
Score: 14
// File Comments
// Test declaring an address as expression
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// The screen
.label SCREEN = $400
// main
main: {
// SCREEN[0] = DATA[0]
// [0] *SCREEN = *DATA -- _deref_pbuc1=_deref_pbuc2
lda DATA
sta SCREEN
// main::@return
// }
// [1] return
rts
}
// File Data
.pc = $1100 "DATA"
// Data to be put on the screen
DATA: .fill $3e8, 0

View File

@ -0,0 +1,4 @@
const byte* DATA[$3e8] = { fill( $3e8, 0) }
const nomodify byte* SCREEN = (byte*) 1024
void main()