1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-10-21 17:24:39 +00:00

Refactored directive parsing slightly.

This commit is contained in:
Jesper Gravgaard 2019-10-17 11:13:46 +02:00
parent 90b2077ac5
commit 8f274f18a6
12 changed files with 1019 additions and 1162 deletions

View File

@ -101,7 +101,9 @@ directive
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
| REGISTER ( PAR_BEGIN ( NAME ) PAR_END)? #directiveRegister
| NOTREGISTER #directiveNotRegister
| ADDRESS_ZEROPAGE | ADDRESS_MAINMEM | ( ADDRESS PAR_BEGIN ( NUMBER ) PAR_END) #directiveMemoryArea
| ADDRESS_ZEROPAGE #directiveMemoryAreaZp
| ADDRESS_MAINMEM #directiveMemoryAreaMain
| ADDRESS PAR_BEGIN ( NUMBER ) PAR_END #directiveMemoryAreaAddress
| INLINE #directiveInline
| VOLATILE #directiveVolatile
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt

File diff suppressed because it is too large Load Diff

View File

@ -390,13 +390,37 @@ public class KickCParserBaseListener implements KickCParserListener {
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { }
@Override public void enterDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { }
@Override public void exitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -236,7 +236,21 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { return visitChildren(ctx); }
@Override public T visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -358,17 +358,41 @@ public interface KickCParserListener extends ParseTreeListener {
*/
void exitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
/**
* Enter a parse tree produced by the {@code directiveMemoryArea}
* Enter a parse tree produced by the {@code directiveMemoryAreaZp}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx);
void enterDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx);
/**
* Exit a parse tree produced by the {@code directiveMemoryArea}
* Exit a parse tree produced by the {@code directiveMemoryAreaZp}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx);
void exitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx);
/**
* Enter a parse tree produced by the {@code directiveMemoryAreaMain}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx);
/**
* Exit a parse tree produced by the {@code directiveMemoryAreaMain}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx);
/**
* Enter a parse tree produced by the {@code directiveMemoryAreaAddress}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void enterDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx);
/**
* Exit a parse tree produced by the {@code directiveMemoryAreaAddress}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
*/
void exitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx);
/**
* Enter a parse tree produced by the {@code directiveInline}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -218,12 +218,26 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
*/
T visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
/**
* Visit a parse tree produced by the {@code directiveMemoryArea}
* Visit a parse tree produced by the {@code directiveMemoryAreaZp}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx);
T visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx);
/**
* Visit a parse tree produced by the {@code directiveMemoryAreaMain}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx);
/**
* Visit a parse tree produced by the {@code directiveMemoryAreaAddress}
* labeled alternative in {@link KickCParser#directive}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx);
/**
* Visit a parse tree produced by the {@code directiveInline}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -162,7 +162,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
/** The current calling convention for procedures. */
Procedure.CallingConvension currentCallingConvention = Procedure.CallingConvension.PHI_CALL;
private Procedure.CallingConvension currentCallingConvention = Procedure.CallingConvension.PHI_CALL;
@Override
public Object visitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) {
@ -174,7 +174,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
/** The current code segment - if null the default segment is used. */
String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
private String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
@Override
public Object visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) {
@ -183,7 +183,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
/** The current data segment - if null the default segment is used. */
String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
private String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
@Override
public Object visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) {
@ -469,7 +469,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
/** ASM Directive specifying clobber registers. */
private class AsmDirectiveClobber implements AsmDirective {
private static class AsmDirectiveClobber implements AsmDirective {
private AsmClobber clobber;
AsmDirectiveClobber(AsmClobber clobber) {
@ -519,8 +519,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Object visitDeclTypes(KickCParser.DeclTypesContext ctx) {
List<KickCParser.DirectiveContext> directive = ctx.directive();
SymbolType varType = (SymbolType) visit(ctx.typeDecl());
this.declVarType = varType;
this.declVarType = (SymbolType) visit(ctx.typeDecl());
this.declVarDirectives = getDirectives(directive);
this.declVarComments = getCommentsSymbol(ctx.getParent());
return null;
@ -712,21 +711,22 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
lValue.setDeclaredMemoryAddress(directiveMemoryArea.address);
}
}
} else if(directive instanceof DirectiveNotRegister) {
lValue.setDeclaredNotRegister(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.LOAD_STORE);
//lValue.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
} else if(directive instanceof DirectiveRegister) {
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
lValue.setDeclaredAsRegister(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
if(directiveRegister.name != null) {
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
Registers.Register register = Registers.getRegister(directiveRegister.name);
if(register == null) {
throw new CompileError("Error! Unknown register " + directiveRegister.name, source);
if(directiveRegister.isRegister) {
lValue.setDeclaredAsRegister(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
if(directiveRegister.name != null) {
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
Registers.Register register = Registers.getRegister(directiveRegister.name);
if(register == null) {
throw new CompileError("Error! Unknown register " + directiveRegister.name, source);
}
lValue.setDeclaredRegister(register);
}
lValue.setDeclaredRegister(register);
} else {
lValue.setDeclaredNotRegister(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.LOAD_STORE);
}
} else {
throw new CompileError("Unsupported variable directive " + directive, source);
@ -829,34 +829,34 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(ctx.NAME() != null) {
name = ctx.NAME().getText();
}
return new DirectiveRegister(name);
return new DirectiveRegister(true, name);
}
@Override
public Object visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) {
return new DirectiveNotRegister();
return new DirectiveRegister(false, null);
}
@Override
public Object visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) {
if(ctx.ADDRESS_ZEROPAGE()!=null) {
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
} else if(ctx.ADDRESS_MAINMEM()!=null) {
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null);
} else if(ctx.ADDRESS()!=null && ctx.NUMBER()!=null) {
Long address = null;
if(ctx.NUMBER() != null) {
try {
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
address = memoryAddress.getInteger();
SymbolVariable.MemoryArea memoryArea = (address<0x100)? SymbolVariable.MemoryArea.ZEROPAGE_MEMORY : SymbolVariable.MemoryArea.MAIN_MEMORY;
return new DirectiveMemoryArea(memoryArea, address);
} catch(NumberFormatException e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx));
}
}
public Object visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) {
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
}
@Override
public Object visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) {
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null);
}
@Override
public Object visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) {
try {
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
Long address = memoryAddress.getInteger();
SymbolVariable.MemoryArea memoryArea = (address<0x100)? SymbolVariable.MemoryArea.ZEROPAGE_MEMORY : SymbolVariable.MemoryArea.MAIN_MEMORY;
return new DirectiveMemoryArea(memoryArea, address);
} catch(NumberFormatException e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx));
}
return null;
}
@Override
@ -1655,19 +1655,19 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
* statement can make sure to output any rValue that has not been output.
* Null if we are not currently monitoring this.
*/
public Set<RValue> exprNotConsumed = null;
private Set<RValue> exprNotConsumed = null;
/**
* Begins monitoring list of expressions not consumed.
*/
void beginNotConsumedTracking() {
private void beginNotConsumedTracking() {
exprNotConsumed = new LinkedHashSet<>();
}
/**
* Ends monitoring list of expressions not consumed.
*/
void endNotConsumedTracking() {
private void endNotConsumedTracking() {
exprNotConsumed = null;
}
@ -1677,7 +1677,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
*
* @param rValue The RValue being consume
*/
void consumeExpr(RValue rValue) {
private void consumeExpr(RValue rValue) {
if(exprNotConsumed != null)
exprNotConsumed.remove(rValue);
}
@ -1688,7 +1688,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
*
* @param rValue The RValue that has been produced but not consumed
*/
void addExprToConsume(RValue rValue) {
private void addExprToConsume(RValue rValue) {
if(exprNotConsumed != null)
exprNotConsumed.add(rValue);
}
@ -1698,7 +1698,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
*
* @return true if the RValue is in the list
*/
boolean notConsumed(RValue rValue) {
private boolean notConsumed(RValue rValue) {
return exprNotConsumed.contains(rValue);
}
@ -2146,7 +2146,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
/** Set containing the token index of all comment blocks that have already been used. */
HashSet<Integer> usedCommentTokenIndices = new HashSet<>();
private HashSet<Integer> usedCommentTokenIndices = new HashSet<>();
/**
* Ensures that the comments have not already been "used" in another context.
@ -2209,9 +2209,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** Function with specific declared calling convention. */
private static class DirectiveCallingConvention implements Directive {
Procedure.CallingConvension callingConvension;
private Procedure.CallingConvension callingConvension;
public DirectiveCallingConvention(Procedure.CallingConvension callingConvension) {
DirectiveCallingConvention(Procedure.CallingConvension callingConvension) {
this.callingConvension = callingConvension;
}
@ -2231,9 +2231,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** Function declared interrupt. */
private static class DirectiveInterrupt implements Directive {
public Procedure.InterruptType interruptType;
Procedure.InterruptType interruptType;
public DirectiveInterrupt(Procedure.InterruptType interruptType) {
DirectiveInterrupt(Procedure.InterruptType interruptType) {
this.interruptType = interruptType;
}
}
@ -2243,32 +2243,28 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
private int alignment;
public DirectiveAlign(int alignment) {
private DirectiveAlign(int alignment) {
this.alignment = alignment;
}
}
/** Variable register allocation. */
/** Variable register or __notregister directive . */
private static class DirectiveRegister implements Directive {
/** Name of register to use for the variable */
/** true if the directive is a register directive. false if it is a notregister directive. */
private boolean isRegister;
/** Name of register to use for the variable (if named) */
private String name;
public DirectiveRegister(String name) {
DirectiveRegister(boolean isRegister, String name) {
this.isRegister = isRegister;
this.name = name;
}
}
/** Variable not regsiter declaration. */
private static class DirectiveNotRegister implements Directive {
public DirectiveNotRegister() {
}
}
/** Variable memory area declaration. */
private static class DirectiveMemoryArea implements Directive {
@ -2278,7 +2274,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** Optional hard-coded address to use for storing the variable. */
private Long address;
public DirectiveMemoryArea(SymbolVariable.MemoryArea memoryArea, Long address) {
DirectiveMemoryArea(SymbolVariable.MemoryArea memoryArea, Long address) {
this.memoryArea = memoryArea;
this.address = address;
}
@ -2290,7 +2286,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
private static class DirectiveReserveZp implements Directive {
List<Integer> reservedZp;
public DirectiveReserveZp(List<Integer> reservedZp) {
DirectiveReserveZp(List<Integer> reservedZp) {
this.reservedZp = reservedZp;
}
@ -2303,20 +2299,20 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
private List<PrePostModifier> preMods;
private Pass0GenerateStatementSequence mainParser;
public PrePostModifierHandler(Pass0GenerateStatementSequence mainParser) {
PrePostModifierHandler(Pass0GenerateStatementSequence mainParser) {
this.mainParser = mainParser;
preMods = new ArrayList<>();
postMods = new ArrayList<>();
}
public static void addPostModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
static void addPostModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
PrePostModifierHandler prePostModifierHandler = new PrePostModifierHandler(parser);
prePostModifierHandler.visit(ctx);
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
addModifierStatements(parser, modifiers, statementSource);
}
public static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser);
modifierHandler.visit(ctx);
List<PrePostModifier> modifiers = modifierHandler.getPreMods();

View File

@ -2718,11 +2718,6 @@ public class TestPrograms {
compileAndCompare("var-register-zp");
}
@Test
public void testVarRegisterZp2() throws IOException, URISyntaxException {
assertError("var-register-zp-2", "Error! Address not on zeropage");
}
@Test
public void testVarRegisterZp3() throws IOException, URISyntaxException {
compileAndCompare("var-register-zp-3");

View File

@ -1,7 +0,0 @@
// Test declaring a variable as register on a specific ZP address
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
main: {
rts
}

View File

@ -1,17 +0,0 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] phi()
to:main::@return
main::@return: scope:[main] from main
[5] return
to:@return

View File

@ -1,203 +0,0 @@
Identified constant variable (signed word*) SCREEN
Identified constant variable (byte) main::i
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) main()
main: scope:[main] from @1
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(void()) main()
(label) main::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
CALL GRAPH
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] phi()
to:main::@return
main::@return: scope:[main] from main
[5] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Test declaring a variable as register on a specific ZP address
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from___b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
jmp __breturn
// main::@return
__breturn:
// [5] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 48 combination
Uplifting [] best 48 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test declaring a variable as register on a specific ZP address
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from___b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
jmp __breturn
// main::@return
__breturn:
// [5] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
Removing instruction main_from___b1:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@return
FINAL ASSEMBLER
Score: 6
// File Comments
// Test declaring a variable as register on a specific ZP address
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
// main::@return
// }
// [5] return
rts
}
// File Data

View File

@ -1,6 +0,0 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@return