mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-21 22:29:07 +00:00
Refactored directive parsing slightly.
This commit is contained in:
parent
90b2077ac5
commit
8f274f18a6
@ -101,7 +101,9 @@ directive
|
|||||||
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
|
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
|
||||||
| REGISTER ( PAR_BEGIN ( NAME ) PAR_END)? #directiveRegister
|
| REGISTER ( PAR_BEGIN ( NAME ) PAR_END)? #directiveRegister
|
||||||
| NOTREGISTER #directiveNotRegister
|
| 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
|
| INLINE #directiveInline
|
||||||
| VOLATILE #directiveVolatile
|
| VOLATILE #directiveVolatile
|
||||||
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
|
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -390,13 +390,37 @@ public class KickCParserBaseListener implements KickCParserListener {
|
|||||||
*
|
*
|
||||||
* <p>The default implementation does nothing.</p>
|
* <p>The default implementation does nothing.</p>
|
||||||
*/
|
*/
|
||||||
@Override public void enterDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { }
|
@Override public void enterDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { }
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* <p>The default implementation does nothing.</p>
|
* <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}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
@ -236,7 +236,21 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
|||||||
* <p>The default implementation returns the result of calling
|
* <p>The default implementation returns the result of calling
|
||||||
* {@link #visitChildren} on {@code ctx}.</p>
|
* {@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}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
@ -358,17 +358,41 @@ public interface KickCParserListener extends ParseTreeListener {
|
|||||||
*/
|
*/
|
||||||
void exitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
|
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}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
* @param ctx the parse tree
|
* @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}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
* @param ctx the parse tree
|
* @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}
|
* Enter a parse tree produced by the {@code directiveInline}
|
||||||
* labeled alternative in {@link KickCParser#directive}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
@ -218,12 +218,26 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
|||||||
*/
|
*/
|
||||||
T visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
|
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}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
* @return the visitor result
|
* @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}
|
* Visit a parse tree produced by the {@code directiveInline}
|
||||||
* labeled alternative in {@link KickCParser#directive}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
@ -162,7 +162,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** The current calling convention for procedures. */
|
/** The current calling convention for procedures. */
|
||||||
Procedure.CallingConvension currentCallingConvention = Procedure.CallingConvension.PHI_CALL;
|
private Procedure.CallingConvension currentCallingConvention = Procedure.CallingConvension.PHI_CALL;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) {
|
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. */
|
/** 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
|
@Override
|
||||||
public Object visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) {
|
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. */
|
/** 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
|
@Override
|
||||||
public Object visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) {
|
public Object visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) {
|
||||||
@ -469,7 +469,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** ASM Directive specifying clobber registers. */
|
/** ASM Directive specifying clobber registers. */
|
||||||
private class AsmDirectiveClobber implements AsmDirective {
|
private static class AsmDirectiveClobber implements AsmDirective {
|
||||||
private AsmClobber clobber;
|
private AsmClobber clobber;
|
||||||
|
|
||||||
AsmDirectiveClobber(AsmClobber clobber) {
|
AsmDirectiveClobber(AsmClobber clobber) {
|
||||||
@ -519,8 +519,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
@Override
|
@Override
|
||||||
public Object visitDeclTypes(KickCParser.DeclTypesContext ctx) {
|
public Object visitDeclTypes(KickCParser.DeclTypesContext ctx) {
|
||||||
List<KickCParser.DirectiveContext> directive = ctx.directive();
|
List<KickCParser.DirectiveContext> directive = ctx.directive();
|
||||||
SymbolType varType = (SymbolType) visit(ctx.typeDecl());
|
this.declVarType = (SymbolType) visit(ctx.typeDecl());
|
||||||
this.declVarType = varType;
|
|
||||||
this.declVarDirectives = getDirectives(directive);
|
this.declVarDirectives = getDirectives(directive);
|
||||||
this.declVarComments = getCommentsSymbol(ctx.getParent());
|
this.declVarComments = getCommentsSymbol(ctx.getParent());
|
||||||
return null;
|
return null;
|
||||||
@ -712,21 +711,22 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
lValue.setDeclaredMemoryAddress(directiveMemoryArea.address);
|
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) {
|
} else if(directive instanceof DirectiveRegister) {
|
||||||
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
||||||
lValue.setDeclaredAsRegister(true);
|
if(directiveRegister.isRegister) {
|
||||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
|
lValue.setDeclaredAsRegister(true);
|
||||||
if(directiveRegister.name != null) {
|
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
|
||||||
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
if(directiveRegister.name != null) {
|
||||||
Registers.Register register = Registers.getRegister(directiveRegister.name);
|
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
||||||
if(register == null) {
|
Registers.Register register = Registers.getRegister(directiveRegister.name);
|
||||||
throw new CompileError("Error! Unknown register " + directiveRegister.name, source);
|
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 {
|
} else {
|
||||||
throw new CompileError("Unsupported variable directive " + directive, source);
|
throw new CompileError("Unsupported variable directive " + directive, source);
|
||||||
@ -829,34 +829,34 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
if(ctx.NAME() != null) {
|
if(ctx.NAME() != null) {
|
||||||
name = ctx.NAME().getText();
|
name = ctx.NAME().getText();
|
||||||
}
|
}
|
||||||
return new DirectiveRegister(name);
|
return new DirectiveRegister(true, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) {
|
public Object visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) {
|
||||||
return new DirectiveNotRegister();
|
return new DirectiveRegister(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) {
|
public Object visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) {
|
||||||
if(ctx.ADDRESS_ZEROPAGE()!=null) {
|
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||||
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
}
|
||||||
} else if(ctx.ADDRESS_MAINMEM()!=null) {
|
|
||||||
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
@Override
|
||||||
} else if(ctx.ADDRESS()!=null && ctx.NUMBER()!=null) {
|
public Object visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) {
|
||||||
Long address = null;
|
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||||
if(ctx.NUMBER() != null) {
|
}
|
||||||
try {
|
|
||||||
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
|
@Override
|
||||||
address = memoryAddress.getInteger();
|
public Object visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) {
|
||||||
SymbolVariable.MemoryArea memoryArea = (address<0x100)? SymbolVariable.MemoryArea.ZEROPAGE_MEMORY : SymbolVariable.MemoryArea.MAIN_MEMORY;
|
try {
|
||||||
return new DirectiveMemoryArea(memoryArea, address);
|
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
|
||||||
} catch(NumberFormatException e) {
|
Long address = memoryAddress.getInteger();
|
||||||
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
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
|
@Override
|
||||||
@ -1655,19 +1655,19 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
* statement can make sure to output any rValue that has not been output.
|
* statement can make sure to output any rValue that has not been output.
|
||||||
* Null if we are not currently monitoring this.
|
* 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.
|
* Begins monitoring list of expressions not consumed.
|
||||||
*/
|
*/
|
||||||
void beginNotConsumedTracking() {
|
private void beginNotConsumedTracking() {
|
||||||
exprNotConsumed = new LinkedHashSet<>();
|
exprNotConsumed = new LinkedHashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends monitoring list of expressions not consumed.
|
* Ends monitoring list of expressions not consumed.
|
||||||
*/
|
*/
|
||||||
void endNotConsumedTracking() {
|
private void endNotConsumedTracking() {
|
||||||
exprNotConsumed = null;
|
exprNotConsumed = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1677,7 +1677,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
*
|
*
|
||||||
* @param rValue The RValue being consume
|
* @param rValue The RValue being consume
|
||||||
*/
|
*/
|
||||||
void consumeExpr(RValue rValue) {
|
private void consumeExpr(RValue rValue) {
|
||||||
if(exprNotConsumed != null)
|
if(exprNotConsumed != null)
|
||||||
exprNotConsumed.remove(rValue);
|
exprNotConsumed.remove(rValue);
|
||||||
}
|
}
|
||||||
@ -1688,7 +1688,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
*
|
*
|
||||||
* @param rValue The RValue that has been produced but not consumed
|
* @param rValue The RValue that has been produced but not consumed
|
||||||
*/
|
*/
|
||||||
void addExprToConsume(RValue rValue) {
|
private void addExprToConsume(RValue rValue) {
|
||||||
if(exprNotConsumed != null)
|
if(exprNotConsumed != null)
|
||||||
exprNotConsumed.add(rValue);
|
exprNotConsumed.add(rValue);
|
||||||
}
|
}
|
||||||
@ -1698,7 +1698,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
*
|
*
|
||||||
* @return true if the RValue is in the list
|
* @return true if the RValue is in the list
|
||||||
*/
|
*/
|
||||||
boolean notConsumed(RValue rValue) {
|
private boolean notConsumed(RValue rValue) {
|
||||||
return exprNotConsumed.contains(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. */
|
/** 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.
|
* 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. */
|
/** Function with specific declared calling convention. */
|
||||||
private static class DirectiveCallingConvention implements Directive {
|
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;
|
this.callingConvension = callingConvension;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2231,9 +2231,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
|
|
||||||
/** Function declared interrupt. */
|
/** Function declared interrupt. */
|
||||||
private static class DirectiveInterrupt implements Directive {
|
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;
|
this.interruptType = interruptType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2243,32 +2243,28 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
|
|
||||||
private int alignment;
|
private int alignment;
|
||||||
|
|
||||||
public DirectiveAlign(int alignment) {
|
private DirectiveAlign(int alignment) {
|
||||||
this.alignment = alignment;
|
this.alignment = alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Variable register allocation. */
|
/** Variable register or __notregister directive . */
|
||||||
private static class DirectiveRegister implements 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;
|
private String name;
|
||||||
|
|
||||||
public DirectiveRegister(String name) {
|
DirectiveRegister(boolean isRegister, String name) {
|
||||||
|
this.isRegister = isRegister;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Variable not regsiter declaration. */
|
|
||||||
private static class DirectiveNotRegister implements Directive {
|
|
||||||
|
|
||||||
public DirectiveNotRegister() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Variable memory area declaration. */
|
/** Variable memory area declaration. */
|
||||||
private static class DirectiveMemoryArea implements Directive {
|
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. */
|
/** Optional hard-coded address to use for storing the variable. */
|
||||||
private Long address;
|
private Long address;
|
||||||
|
|
||||||
public DirectiveMemoryArea(SymbolVariable.MemoryArea memoryArea, Long address) {
|
DirectiveMemoryArea(SymbolVariable.MemoryArea memoryArea, Long address) {
|
||||||
this.memoryArea = memoryArea;
|
this.memoryArea = memoryArea;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
}
|
}
|
||||||
@ -2290,7 +2286,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
private static class DirectiveReserveZp implements Directive {
|
private static class DirectiveReserveZp implements Directive {
|
||||||
List<Integer> reservedZp;
|
List<Integer> reservedZp;
|
||||||
|
|
||||||
public DirectiveReserveZp(List<Integer> reservedZp) {
|
DirectiveReserveZp(List<Integer> reservedZp) {
|
||||||
this.reservedZp = reservedZp;
|
this.reservedZp = reservedZp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2303,20 +2299,20 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
private List<PrePostModifier> preMods;
|
private List<PrePostModifier> preMods;
|
||||||
private Pass0GenerateStatementSequence mainParser;
|
private Pass0GenerateStatementSequence mainParser;
|
||||||
|
|
||||||
public PrePostModifierHandler(Pass0GenerateStatementSequence mainParser) {
|
PrePostModifierHandler(Pass0GenerateStatementSequence mainParser) {
|
||||||
this.mainParser = mainParser;
|
this.mainParser = mainParser;
|
||||||
preMods = new ArrayList<>();
|
preMods = new ArrayList<>();
|
||||||
postMods = 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 prePostModifierHandler = new PrePostModifierHandler(parser);
|
||||||
prePostModifierHandler.visit(ctx);
|
prePostModifierHandler.visit(ctx);
|
||||||
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
|
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
|
||||||
addModifierStatements(parser, modifiers, statementSource);
|
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);
|
PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser);
|
||||||
modifierHandler.visit(ctx);
|
modifierHandler.visit(ctx);
|
||||||
List<PrePostModifier> modifiers = modifierHandler.getPreMods();
|
List<PrePostModifier> modifiers = modifierHandler.getPreMods();
|
||||||
|
@ -2718,11 +2718,6 @@ public class TestPrograms {
|
|||||||
compileAndCompare("var-register-zp");
|
compileAndCompare("var-register-zp");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVarRegisterZp2() throws IOException, URISyntaxException {
|
|
||||||
assertError("var-register-zp-2", "Error! Address not on zeropage");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVarRegisterZp3() throws IOException, URISyntaxException {
|
public void testVarRegisterZp3() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("var-register-zp-3");
|
compileAndCompare("var-register-zp-3");
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
(label) @1
|
|
||||||
(label) @begin
|
|
||||||
(label) @end
|
|
||||||
(void()) main()
|
|
||||||
(label) main::@return
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user