mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-24 16:30:54 +00:00
Updated to ANTLR4.9. Merged Andrzej Śliwa implementation of __address() support for constant expressions branch address_with_expression_value. Closes !1
This commit is contained in:
commit
82a045934d
13
.idea/libraries/Maven__org_antlr_antlr4_4_8_1.xml
generated
13
.idea/libraries/Maven__org_antlr_antlr4_4_8_1.xml
generated
@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: org.antlr:antlr4:4.8-1">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.8-1/antlr4-4.8-1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.8-1/antlr4-4.8-1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.8-1/antlr4-4.8-1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
13
.idea/libraries/Maven__org_antlr_antlr4_4_9.xml
generated
Normal file
13
.idea/libraries/Maven__org_antlr_antlr4_4_9.xml
generated
Normal file
@ -0,0 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: org.antlr:antlr4:4.9">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9/antlr4-4.9.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9/antlr4-4.9-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9/antlr4-4.9-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
@ -1,13 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: org.antlr:antlr4-runtime:4.8-1">
|
||||
<library name="Maven: org.antlr:antlr4-runtime:4.9">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.8-1/antlr4-runtime-4.8-1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9/antlr4-runtime-4.9.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.8-1/antlr4-runtime-4.8-1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9/antlr4-runtime-4.9-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.8-1/antlr4-runtime-4.8-1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9/antlr4-runtime-4.9-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
@ -11,11 +11,11 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:antlr4:4.8-1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:antlr4:4.9" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:ST4:4.3" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.abego.treelayout:org.abego.treelayout.core:1.0.3" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: com.ibm.icu:icu4j:61.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.8-1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.9" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.2" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.2" level="project" />
|
||||
|
4
pom.xml
4
pom.xml
@ -27,13 +27,13 @@
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.8-1</version>
|
||||
<version>4.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.8-1</version>
|
||||
<version>4.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
1068
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
1068
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
@ -138,12 +139,16 @@ public class Directive {
|
||||
/** Variable hardcoded __address() directive */
|
||||
public static class Address extends Directive {
|
||||
|
||||
/** Optional hard-coded address to use for storing the variable. */
|
||||
public Long address;
|
||||
/** Expression for calculating the address. */
|
||||
public ConstantValue addressValue;
|
||||
|
||||
public Address(Long address) {
|
||||
/** Optional hard-coded address to use for storing the variable. */
|
||||
public Long addressLiteral;
|
||||
|
||||
public Address(ConstantValue addressValue, Long addressLiteral) {
|
||||
super("__address");
|
||||
this.address = address;
|
||||
this.addressValue = addressValue;
|
||||
this.addressLiteral = addressLiteral;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
|
||||
import java.util.List;
|
||||
@ -322,7 +323,7 @@ public class VariableBuilder {
|
||||
return Variable.MemoryArea.MAIN_MEMORY;
|
||||
Directive.Address addressDirective = findDirective(Directive.Address.class, directives);
|
||||
if(addressDirective != null)
|
||||
return (addressDirective.address < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY;
|
||||
return (addressDirective.addressLiteral < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY;
|
||||
else if(!isConstant() && isOptimize())
|
||||
return Variable.MemoryArea.ZEROPAGE_MEMORY;
|
||||
else {
|
||||
@ -359,11 +360,11 @@ public class VariableBuilder {
|
||||
*
|
||||
* @return The memory alignment
|
||||
*/
|
||||
public Long getAddress() {
|
||||
public ConstantValue getAddress() {
|
||||
Directive.Address addressDirective = findDirective(Directive.Address.class, directives);
|
||||
if(addressDirective != null) {
|
||||
if(isArray()) {
|
||||
return addressDirective.address;
|
||||
return addressDirective.addressValue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -382,12 +383,12 @@ public class VariableBuilder {
|
||||
|
||||
Directive.Address addressDirective = findDirective(Directive.Address.class, directives);
|
||||
if(addressDirective != null) {
|
||||
Variable.MemoryArea memoryArea = (addressDirective.address < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY;
|
||||
Variable.MemoryArea memoryArea = (addressDirective.addressLiteral < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY;
|
||||
if(Variable.MemoryArea.ZEROPAGE_MEMORY.equals(memoryArea)) {
|
||||
return new Registers.RegisterZpMem(addressDirective.address.intValue(), -1, true);
|
||||
return new Registers.RegisterZpMem(addressDirective.addressLiteral.intValue(), -1, true);
|
||||
} else {
|
||||
// TODO: Fix VariableRef for the hard-coded register
|
||||
return new Registers.RegisterMainMem(null, -1, addressDirective.address);
|
||||
return new Registers.RegisterMainMem(null, -1, addressDirective.addressLiteral);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,6 +651,26 @@ public interface ProgramValue {
|
||||
|
||||
}
|
||||
|
||||
/** The memory address of a variable. */
|
||||
class ProgramValueMemoryAddress implements ProgramValue {
|
||||
private final Variable constantVar;
|
||||
|
||||
ProgramValueMemoryAddress(Variable constantVar) {
|
||||
this.constantVar = constantVar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get() {
|
||||
return constantVar.getMemoryAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Value val) {
|
||||
constantVar.setMemoryAddress((ConstantValue) val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Bytes inside inline kickasm code. */
|
||||
class ProgramValueKickAsmBytes implements ProgramValue {
|
||||
|
||||
|
@ -58,6 +58,9 @@ public class ProgramValueIterator {
|
||||
if(variable.isArray()) {
|
||||
execute(new ProgramValue.ProgramValueArraySize(variable), programValueHandler, null, null, null);
|
||||
}
|
||||
if(variable.getMemoryAddress() != null) {
|
||||
execute(new ProgramValue.ProgramValueMemoryAddress(variable), programValueHandler, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,7 +95,7 @@ public class Variable implements Symbol {
|
||||
private Integer memoryAlignment;
|
||||
|
||||
/** Specifies that the variable must be placed at an absolute address in memory. Only allowed for arrays & strings. [Only Variables in memory and arrays] */
|
||||
private Long memoryAddress;
|
||||
private ConstantValue memoryAddress;
|
||||
|
||||
/** The data segment to put the variable into (if it is allocated in memory). [Only variables stored in memory and arrays] */
|
||||
private String dataSegment;
|
||||
@ -582,11 +582,11 @@ public class Variable implements Symbol {
|
||||
this.memoryAlignment = memoryAlignment;
|
||||
}
|
||||
|
||||
public Long getMemoryAddress() {
|
||||
public ConstantValue getMemoryAddress() {
|
||||
return memoryAddress;
|
||||
}
|
||||
|
||||
public void setMemoryAddress(Long memoryAddress) {
|
||||
public void setMemoryAddress(ConstantValue memoryAddress) {
|
||||
this.memoryAddress = memoryAddress;
|
||||
}
|
||||
|
||||
|
@ -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/jespergravgaard/c64/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 =
|
||||
|
@ -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
@ -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/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
|
||||
package dk.camelot64.kickc.parser;
|
||||
|
||||
|
||||
|
@ -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/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
|
||||
package dk.camelot64.kickc.parser;
|
||||
|
||||
|
||||
|
@ -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/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
|
||||
package dk.camelot64.kickc.parser;
|
||||
|
||||
|
||||
|
@ -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/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.9
|
||||
package dk.camelot64.kickc.parser;
|
||||
|
||||
|
||||
|
@ -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(addressAsConstantValue, 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));
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ public class Pass4CodeGeneration {
|
||||
// Set segment
|
||||
setCurrentSegment(constantVar.getDataSegment(), asm);
|
||||
// Set absolute address
|
||||
asm.addLine(new AsmSetPc(asmName, AsmFormat.getAsmNumber(constantVar.getMemoryAddress())));
|
||||
asm.addLine(new AsmSetPc(asmName, AsmFormat.getAsmConstant(program, constantVar.getMemoryAddress(), 99, scopeRef)));
|
||||
// Add any comments
|
||||
generateComments(asm, constantVar.getComments());
|
||||
// Add any alignment
|
||||
|
@ -1069,6 +1069,11 @@ public class TestPrograms {
|
||||
compileAndCompare("address-9.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressWithExpressionValue() throws IOException, URISyntaxException {
|
||||
compileAndCompare("address-with-expression-value.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddress8() throws IOException, URISyntaxException {
|
||||
compileAndCompare("address-8.c");
|
||||
@ -5061,8 +5066,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)
|
||||
|
16
src/test/kc/address-with-expression-value.c
Normal file
16
src/test/kc/address-with-expression-value.c
Normal 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];
|
||||
}
|
||||
|
18
src/test/ref/address-with-expression-value.asm
Normal file
18
src/test/ref/address-with-expression-value.asm
Normal file
@ -0,0 +1,18 @@
|
||||
// Test declaring an address as expression
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const var1 = $800
|
||||
.const var2 = $900
|
||||
// The screen
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
// SCREEN[0] = DATA[0]
|
||||
lda DATA
|
||||
sta SCREEN
|
||||
// }
|
||||
rts
|
||||
}
|
||||
.pc = var1+var2 "DATA"
|
||||
// Data to be put on the screen
|
||||
DATA: .fill $3e8, 0
|
9
src/test/ref/address-with-expression-value.cfg
Normal file
9
src/test/ref/address-with-expression-value.cfg
Normal 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
|
||||
|
151
src/test/ref/address-with-expression-value.log
Normal file
151
src/test/ref/address-with-expression-value.log
Normal file
@ -0,0 +1,151 @@
|
||||
|
||||
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()
|
||||
const nomodify word var1 = $800
|
||||
const nomodify word var2 = $900
|
||||
|
||||
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
|
||||
.const var1 = $800
|
||||
.const var2 = $900
|
||||
// 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 = var1+var2 "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()
|
||||
const nomodify word var1 = $800
|
||||
const nomodify word var2 = $900
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 14
|
||||
|
||||
// File Comments
|
||||
// Test declaring an address as expression
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.const var1 = $800
|
||||
.const var2 = $900
|
||||
// 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 = var1+var2 "DATA"
|
||||
// Data to be put on the screen
|
||||
DATA: .fill $3e8, 0
|
||||
|
6
src/test/ref/address-with-expression-value.sym
Normal file
6
src/test/ref/address-with-expression-value.sym
Normal file
@ -0,0 +1,6 @@
|
||||
const byte* DATA[$3e8] = { fill( $3e8, 0) }
|
||||
const nomodify byte* SCREEN = (byte*) 1024
|
||||
void main()
|
||||
const nomodify word var1 = $800
|
||||
const nomodify word var2 = $900
|
||||
|
Loading…
x
Reference in New Issue
Block a user