diff --git a/src/main/antlr4/dk/camelot64/kickc/parser/KickCParser.g4 b/src/main/antlr4/dk/camelot64/kickc/parser/KickCParser.g4 index 3b20e6c22..070ecaee8 100644 --- a/src/main/antlr4/dk/camelot64/kickc/parser/KickCParser.g4 +++ b/src/main/antlr4/dk/camelot64/kickc/parser/KickCParser.g4 @@ -162,7 +162,7 @@ directive | EXTERN #directiveExtern | EXPORT #directiveExport | INLINE #directiveInline - | FAR PAR_BEGIN ( NUMBER ) PAR_END #directiveFar + | FAR PAR_BEGIN NAME COMMA NUMBER (COMMA NAME COMMA NAME COMMA NAME)? PAR_END #directiveFar | INTRINSIC #directiveIntrinsic | INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt | LOCAL_RESERVE PAR_BEGIN pragmaParam ( COMMA pragmaParam )* PAR_END #directiveReserveZp diff --git a/src/main/fragment/mos6502-common/call_far_cx16_entry.asm b/src/main/fragment/mos6502-common/call_far_cx16_execute.asm similarity index 100% rename from src/main/fragment/mos6502-common/call_far_cx16_entry.asm rename to src/main/fragment/mos6502-common/call_far_cx16_execute.asm diff --git a/src/main/fragment/mos6502-common/call_far_cx16_exit.asm b/src/main/fragment/mos6502-common/call_far_cx16_finalize.asm similarity index 100% rename from src/main/fragment/mos6502-common/call_far_cx16_exit.asm rename to src/main/fragment/mos6502-common/call_far_cx16_finalize.asm diff --git a/src/main/fragment/mos6502-common/call_far_cx16_prepare.asm b/src/main/fragment/mos6502-common/call_far_cx16_prepare.asm new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 812cffe2a..cc8b197cd 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -278,7 +278,6 @@ public class Compiler { getLog().append(program.getGraph().toString(program)); } new Pass1ProcedureInline(program).execute(); - new Pass1ProcedureFar(program).execute(); // Implements far calls to procedures defined in a bank. See https://gitlab.com/Flight_Control/kickc/-/commits/far-call-isolated new PassNStatementIndices(program).step(); program.clearCallGraph(); new Pass1AssertNoRecursion(program).execute(); diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java index 41e3a76e8..c39c919d9 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java @@ -18,7 +18,6 @@ import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.values.*; -import kickass.pass.values.StringValue; /** * Creates an ASM Fragment specification for a statement in the control flow graph. @@ -43,16 +42,16 @@ final public class AsmFragmentInstanceSpecBuilder { } /** - * Create a fragment instance spec factory for a far call entry + * Create a fragment instance spec factory for a far call prepare * * @param bankFar The bank where the procedure is to be called. * @param procedureName The full name of the procedure. * @param program The program * @return the fragment instance spec factory */ - public static AsmFragmentInstanceSpec farCallEntry(Long bankFar, String procedureName, Program program) { + public static AsmFragmentInstanceSpec farCallPrepare(Long bankFar, String procedureName, Program program) { AsmFragmentBindings bindings = new AsmFragmentBindings(program); - AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.EntryExit.Entry); + AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.PrepareExecuteFinalize.Prepare); ScopeRef codeScope = program.getScope().getRef(); // ScopeRef codeScope = program.getStatementInfos().getBlock(call).getScope(); bindings.bind("c1", new ConstantInteger(bankFar)); @@ -61,16 +60,34 @@ final public class AsmFragmentInstanceSpecBuilder { } /** - * Create a fragment instance spec factory for a far call exit + * Create a fragment instance spec factory for a far call execute + * + * @param bankFar The bank where the procedure is to be called. + * @param procedureName The full name of the procedure. + * @param program The program + * @return the fragment instance spec factory + */ + public static AsmFragmentInstanceSpec farCallExecute(Long bankFar, String procedureName, Program program) { + AsmFragmentBindings bindings = new AsmFragmentBindings(program); + AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.PrepareExecuteFinalize.Execute); + ScopeRef codeScope = program.getScope().getRef(); +// ScopeRef codeScope = program.getStatementInfos().getBlock(call).getScope(); + bindings.bind("c1", new ConstantInteger(bankFar)); + bindings.bind("la1", new LabelRef(procedureName)); + return new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); + } + + /** + * Create a fragment instance spec factory for a far call finalize * * @param bankFar The bank where the procedure is to be called. * @param procedureName The full name of the procedure. * @param program The program * @return the fragment instance spec factory */ - public static AsmFragmentInstanceSpec farCallExit(Long bankFar, String procedureName, Program program) { + public static AsmFragmentInstanceSpec farCallFinalize(Long bankFar, String procedureName, Program program) { AsmFragmentBindings bindings = new AsmFragmentBindings(program); - AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.EntryExit.Exit); + AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.PrepareExecuteFinalize.Finalize); ScopeRef codeScope = program.getScope().getRef(); bindings.bind("c1", new ConstantInteger(bankFar)); bindings.bind("la1", new LabelRef(procedureName)); diff --git a/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java index 28797a17d..45a2689e7 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java +++ b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java @@ -78,23 +78,24 @@ public interface AsmFragmentSignature { final private Long bankFar; final private String targetPlatform; - public enum EntryExit { - Exit, - Entry + public enum PrepareExecuteFinalize { + Prepare, + Execute, + Finalize } - final private CallFar.EntryExit entryExit; + final private PrepareExecuteFinalize far; - public CallFar(Long bankFar, String targetPlatform, CallFar.EntryExit entryExit) { + public CallFar(Long bankFar, String targetPlatform, PrepareExecuteFinalize far) { this.bankFar = bankFar; this.targetPlatform = targetPlatform; - this.entryExit = entryExit; + this.far = far; } @Override public String getName() { - return "call_far" + "_" + targetPlatform + "_" + entryExit.name().toLowerCase(); + return "call_far" + "_" + targetPlatform + "_" + far.name().toLowerCase(); } } diff --git a/src/main/java/dk/camelot64/kickc/model/Directive.java b/src/main/java/dk/camelot64/kickc/model/Directive.java index f8f842a63..e155d5587 100644 --- a/src/main/java/dk/camelot64/kickc/model/Directive.java +++ b/src/main/java/dk/camelot64/kickc/model/Directive.java @@ -46,13 +46,41 @@ public class Directive { /** Function declared far. */ static public class Far extends Directive { - public Long bankFar; + private String farSegmentName; + private Long farSegmentBank; + private String farProcedurePrepare; + private String farProcedureExecute; + private String farProcedureFinalize; - public Far(Long bankFar) { - super("__far"); - this.bankFar = bankFar; + + public Far(String farSegmentName, Long farSegmentBank, String farProcedurePrepare, String farProcedureExecute, String farProcedureFinalize) { + super("far" ); + this.farSegmentName = farSegmentName; + this.farSegmentBank = farSegmentBank; + this.farProcedurePrepare = farProcedurePrepare; + this.farProcedureExecute = farProcedureExecute; + this.farProcedureFinalize = farProcedureFinalize; } + public String getFarSegmentName() { + return farSegmentName; + } + + public Long getFarSegmentBank() { + return farSegmentBank; + } + + public String getFarProcedurePrepare() { + return farProcedurePrepare; + } + + public String getFarProcedureExecute() { + return farProcedureExecute; + } + + public String getFarProcedureFinalize() { + return farProcedureFinalize; + } } /** Function declared intrinsic. */ diff --git a/src/main/java/dk/camelot64/kickc/model/FarSegment.java b/src/main/java/dk/camelot64/kickc/model/FarSegment.java index d297adbad..18f8dd976 100644 --- a/src/main/java/dk/camelot64/kickc/model/FarSegment.java +++ b/src/main/java/dk/camelot64/kickc/model/FarSegment.java @@ -1,32 +1,43 @@ package dk.camelot64.kickc.model; -import dk.camelot64.kickc.model.symbols.Procedure; - -import java.util.List; - /** A far segment. */ public class FarSegment { - private String name; - private Integer bank; - private String call_prepare; - private String call_execute; - private String call_finalize; + private final String farSegment; + private Long farBank; + private final String procedurePrepare; + private final String procedureExecute; + private final String procedureFinalize; - public FarSegment(String name, Integer bank, String call_prepare, String call_execute, String call_finalize) { - this.name = name; - this.bank = bank; - this.call_prepare = call_prepare; - this.call_execute = call_execute; - this.call_finalize = call_finalize; + public FarSegment(String name, Long bank, String procedurePrepare, String procedureExecute, String procedureFinalize) { + this.farSegment = name; + this.farBank = bank; + this.procedurePrepare = procedurePrepare; + this.procedureExecute = procedureExecute; + this.procedureFinalize = procedureFinalize; } - public String getName() { - return name; + public String getFarSegment() { + return farSegment; } + public Long getFarBank() { + return farBank; + } - public Integer getBank() { - return bank; + public void setFarBank(Long farBank) { + this.farBank = farBank; + } + + public String getProcedurePrepare() { + return procedurePrepare; + } + + public String getProcedureExecute() { + return procedureExecute; + } + + public String getProcedureFinalize() { + return procedureFinalize; } } diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index bcd720852..898c50028 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -8,13 +8,11 @@ import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.values.LabelRef; import dk.camelot64.kickc.model.values.ProcedureRef; +import dk.camelot64.kickc.parser.KickCParser; import dk.camelot64.kickc.passes.calcs.*; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** A KickC Intermediate Compiler Language (ICL) Program */ public class Program { @@ -107,6 +105,8 @@ public class Program { private NaturalLoopSet loopSet; /** The register weight of all variables describing how much the variable would theoretically gain from being in a register. PASS 3-5 (CACHED ON-DEMAND) */ private VariableRegisterWeights variableRegisterWeights; + /** All #pragma code segments. Collected during parsing. These are used by the far() pragmas to validate if the code segment exists during compilation.*/ + private final Map pragmaCodeSegs; public Program() { this.outputFileManager = new OutputFileManager(); @@ -119,6 +119,8 @@ public class Program { this.asmResourceFiles = new ArrayList<>(); this.reservedZps = new ArrayList<>(); this.procedureCompilations = new LinkedHashMap<>(); + this.pragmaCodeSegs = new HashMap<>(); // Used to collect all pragma code segments. + } /** @@ -539,4 +541,7 @@ public class Program { return sizeInfo.toString(); } + public Map getPragmaCodeSegs() { + return pragmaCodeSegs; + } } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java index 7c375e71c..c1b761e7f 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.model.symbols; import dk.camelot64.kickc.model.Comment; +import dk.camelot64.kickc.model.FarSegment; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.StatementSource; import dk.camelot64.kickc.model.types.SymbolType; @@ -27,8 +28,6 @@ public class Procedure extends Scope { private boolean declaredInline; /** true if the procedure is declared far. */ private boolean declaredFar; - /** contains the far bank. */ - private Long bankFar; /** True if the procedure is declared intrinsic. */ private boolean declaredIntrinsic; /** The type of interrupt that the procedure serves. Null for all procedures not serving an interrupt. */ @@ -45,6 +44,9 @@ public class Procedure extends Scope { private boolean isConstructor; /** The source of the procedure definition. */ private StatementSource definitionSource; + /** The far segment information. Collected during parsing. These are used to compare with the current currentFarSegment to decide a near or a far call, and to keep inline calling routines.*/ + private FarSegment farSegment; + /** The names of all legal intrinsic procedures. */ final public static List INTRINSIC_PROCEDURES = Arrays.asList( @@ -54,10 +56,17 @@ public class Procedure extends Scope { Pass1ByteXIntrinsicRewrite.INTRINSIC_MAKELONG4 ); + public FarSegment getFarSegment() { + return farSegment; + } + + public void setFarSegment(FarSegment farSegment) { + this.farSegment = farSegment; + } + + /** The method for passing parameters and return value to the procedure. */ public enum CallingConvention { - /** Far call in a cx16 bank using the https://github.com/commanderx16/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-jsrfar routine*/ - FAR_CALL("__far"), /** Parameters and return value handled through PHI-transitions. */ PHI_CALL("__phicall"), /** Parameters and return value over the stack. */ @@ -91,12 +100,11 @@ public class Procedure extends Scope { /** The calling convention used for this procedure. */ private CallingConvention callingConvention; - public Procedure(String name, SymbolTypeProcedure procedureType, Scope parentScope, String codeSegment, String dataSegment, CallingConvention callingConvention) { + public Procedure(String name, SymbolTypeProcedure procedureType, Scope parentScope, String codeSegment, String dataSegment, CallingConvention callingConvention, FarSegment farSegment) { super(name, parentScope, dataSegment); this.procedureType = procedureType; this.declaredInline = false; - this.declaredFar = false; - this.bankFar = 0L; + this.farSegment = farSegment; this.interruptType = null; this.comments = new ArrayList<>(); this.codeSegment = codeSegment; @@ -207,17 +215,14 @@ public class Procedure extends Scope { } public boolean isDeclaredFar() { - return declaredFar; + return farSegment != null; } - public void setDeclaredFar(boolean declaredFar) { - this.declaredFar = declaredFar; - } - - public Long getBankFar() { return this.bankFar; } - - public void setBankFar(Long bankFar) { - this.bankFar = bankFar; + public Long getFarBank() { + if(farSegment!=null) + return farSegment.getFarBank(); + else + return 0L; } public String getInterruptType() { diff --git a/src/main/java/dk/camelot64/kickc/parser/CParser.java b/src/main/java/dk/camelot64/kickc/parser/CParser.java index a01d0194a..806287556 100644 --- a/src/main/java/dk/camelot64/kickc/parser/CParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/CParser.java @@ -107,13 +107,13 @@ public class CParser { */ public static final String PRAGMA_RESOURCE = "resource"; /** - * #pragma far_seg(...) specifies the scope of the sequent functions to be far. Segments are defined in the linker file. + * #pragma far(...) specifies the scope of the sequent functions to be far. Segments are defined in the linker file. */ - public static final String PRAGMA_FAR_SEG = "far_seg"; + public static final String PRAGMA_FAR = "far"; /** - * #pragma near_seg specifies the scope of the sequent functions to be near. Segments are defined in the linker file. + * #pragma near specifies the scope of the sequent functions to be near. Segments are defined in the linker file. */ - public static final String PRAGMA_NEAR_SEG = "near_seg"; + public static final String PRAGMA_NEAR = "near"; /** * The Program. diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 67f93854c..00cde33d7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -43,10 +43,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor scopeStack; /** All #pragma constructor_for() statements. Collected during parsing and handled by {@link #generate()} before returning. */ private final List pragmaConstructorFors; - /** All #pragma code segments. Collected during parsing. These are used by the far_seg pragmas to validate if the code segment exists during compilation.*/ - private final Map pragmaCodeSegs; - /** All #pragma far segments. Collected during parsing. These are used to compare with the current currentFarSegment to decide a near or a far call, and to keep inline calling routines.*/ - private final Map pragmaFarSegs; public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, Procedure.CallingConvention initialCallingConvention, StringEncoding defaultEncoding, String defaultInterruptType) { @@ -57,8 +53,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor(); // Used to collect all pragma code segments. - this.pragmaFarSegs = new HashMap<>(); // Used to collect all pragma far segments. this.currentInterruptType = defaultInterruptType; scopeStack.push(program.getScope()); } @@ -137,7 +131,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL); + initProc = new Procedure(SymbolRef.INIT_PROC_NAME, new SymbolTypeProcedure(SymbolType.VOID, new ArrayList<>()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL, null); initProc.setDeclaredInline(true); initProc.setParameters(new ArrayList<>()); program.getScope().add(initProc); @@ -194,7 +188,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL); + final Procedure startProcedure = new Procedure(SymbolRef.START_PROC_NAME, new SymbolTypeProcedure(SymbolType.VOID, new ArrayList<>()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL, null); startProcedure.setParameters(new ArrayList<>()); program.getScope().add(startProcedure); final ProcedureCompilation startProcedureCompilation = program.createProcedureCompilation(startProcedure.getRef()); @@ -296,27 +290,24 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor 7) { - final String call_prepare = pragmaParamName(ctx.pragmaParam(2)); - final String call_execute = pragmaParamName(ctx.pragmaParam(3)); - final String call_finalize = pragmaParamName(ctx.pragmaParam(4)); - this.pragmaFarSegs.put(this.currentFarSegment, new FarSegment(pragmaFarSegment, pragmaFarBank.intValue(), call_prepare, call_execute, call_finalize)); - } else { - this.pragmaFarSegs.put(this.currentFarSegment, new FarSegment(pragmaFarSegment, pragmaFarBank.intValue(), "", "", "")); - } + if (size > 7) { + final String call_prepare = pragmaParamName(ctx.pragmaParam(2)); + final String call_execute = pragmaParamName(ctx.pragmaParam(3)); + final String call_finalize = pragmaParamName(ctx.pragmaParam(4)); + this.currentFarSegment = new FarSegment(pragmaFarSegment, pragmaFarBank.longValue(), call_prepare, call_execute, call_finalize); + } else { + this.currentFarSegment = new FarSegment(pragmaFarSegment, pragmaFarBank.longValue(), "", "", ""); } } else { throw new CompileError("Expected at least 2 pragma parameters. Found '" + ctx.getText() + "'.", new StatementSource(ctx)); @@ -325,8 +316,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor 1) { - bankFar = Long.valueOf(ctx.getChild(2).getText()); - } else { - bankFar = 0L; + String farSegmentName = ""; + Long farSegmentBank = 0L; + String farProcedurePrepare = null; + String farProcedureExecute = null; + String farProcedureFinalize = null; + if(this.currentFarSegment != null) { + farSegmentName = this.currentFarSegment.getFarSegment(); + farSegmentBank = this.currentFarSegment.getFarBank(); + farProcedurePrepare = this.currentFarSegment.getProcedurePrepare(); + farProcedureExecute = this.currentFarSegment.getProcedureExecute(); + farProcedureFinalize = this.currentFarSegment.getProcedureFinalize(); } - return new Directive.Far(bankFar); + + if(ctx.getChildCount() >= 5) { + farSegmentName = ctx.getChild(2).getText(); + farSegmentBank = Long.valueOf(ctx.getChild(4).getText()); + } + + if(ctx.getChildCount() == 11) { + farProcedurePrepare = ctx.getChild(6).getText(); + farProcedureExecute = ctx.getChild(8).getText(); + farProcedureFinalize = ctx.getChild(10).getText(); + } + + return new Directive.Far(farSegmentName, farSegmentBank, farProcedurePrepare, farProcedureExecute, farProcedureFinalize); } @Override @@ -2539,7 +2548,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor__start::@1] + // __start::@1 + // [3] callexecute main -- call_vprc1 + jsr main + // __start::@return + // [4] return + rts +} + // printother +printother: { + .label i = 2 + // [6] phi from printother to printother::@1 [phi:printother->printother::@1] + // [6] phi printother::i#2 = 0 [phi:printother->printother::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z i + // [6] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1] + // [6] phi printother::i#2 = printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy + // printother::@1 + __b1: + // (SCREEN+40)[i]++; + // [7] (SCREEN+$28)[printother::i#2] = ++ (SCREEN+$28)[printother::i#2] -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1 + ldx.z i + inc SCREEN+$28,x + // for(char i:0..5) + // [8] printother::i#1 = ++ printother::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // [9] if(printother::i#1!=6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #6 + cmp.z i + bne __b1 + // printother::@return + // } + // [10] return + rts +} + // incval +incval: { + // val++; + // [11] val = ++ val -- vbuz1=_inc_vbuz1 + inc.z val + // incval::@return + // } + // [12] return + rts +} + // printval +printval: { + // SCREEN[0] = val + // [13] *SCREEN = val -- _deref_pbuc1=vbuz1 + lda.z val + sta SCREEN + // printval::@return + // } + // [14] return + rts +} + // ival +ival: { + // incval() + // [16] callexecute incval -- call_far_cx16_exit + jsr $ff6e + .byte incval + .byte $15 + // ival::@return + // } + // [17] return + rts +} + // pval +pval: { + // printval() + // [19] callexecute printval -- call_far_cx16_exit + jsr $ff6e + .byte printval + .byte $14 + // pval::@return + // } + // [20] return + rts +} + // main +main: { + .label i = 4 + // [22] phi from main to main::@1 [phi:main->main::@1] + // [22] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z i + // [22] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + // [22] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy + // main::@1 + __b1: + // pval() + // [23] callexecute pval -- call_far_cx16_exit + jsr $ff6e + .byte pval + .byte $14 + // printother() + // [24] callexecute printother -- call_vprc1 + jsr printother + // ival() + // [25] callexecute ival -- call_far_cx16_exit + jsr $ff6e + .byte ival + .byte $15 + // for(char i:0..5) + // [26] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // [27] if(main::i#1!=6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #6 + cmp.z i + bne __b1 + // main::@return + // } + // [28] return + rts +} + // File Data diff --git a/src/test/target/procedure-callingconvention-stack-far-3.dbg b/src/test/target/procedure-callingconvention-stack-far-3.dbg new file mode 100644 index 000000000..51e9414f5 --- /dev/null +++ b/src/test/target/procedure-callingconvention-stack-far-3.dbg @@ -0,0 +1,153 @@ + + + 0,KickAss.jar:/include/autoinclude.asm + 1,D:\Users\svenv\OneDrive\Documents\GitHub\kickc\src\test\target\procedure-callingconvention-stack-far-3.asm + + + + + + + + $0801,$0802,0,38,2,38,6 + $0803,$0804,0,39,5,39,9 + $0805,$0805,0,40,5,40,9 + $0806,$0809,0,41,2,41,6 + $080a,$080a,0,42,2,42,6 + $080b,$080c,0,44,5,44,9 + + + $080d,$080e,1,23,5,23,7 + $080f,$0810,1,24,5,24,7 + $0811,$0813,1,28,5,28,7 + $0814,$0814,1,31,5,31,7 + $0815,$0816,1,38,5,38,7 + $0817,$0818,1,39,5,39,7 + $0819,$081a,1,46,5,46,7 + $081b,$081d,1,47,5,47,7 + $081e,$081f,1,50,5,50,7 + $0820,$0821,1,52,5,52,7 + $0822,$0823,1,53,5,53,7 + $0824,$0825,1,54,5,54,7 + $0826,$0826,1,58,5,58,7 + $0827,$0828,1,64,5,64,7 + $0829,$0829,1,68,5,68,7 + $082a,$082b,1,74,5,74,7 + $082c,$082e,1,75,5,75,7 + $082f,$082f,1,79,5,79,7 + $0830,$0832,1,85,5,85,7 + $0833,$0833,1,86,5,86,9 + $0834,$0834,1,87,5,87,9 + $0835,$0835,1,88,5,88,9 + $0836,$0836,1,92,5,92,7 + $0837,$0839,1,98,5,98,7 + $083a,$083a,1,99,5,99,9 + $083b,$083b,1,100,5,100,9 + $083c,$083c,1,101,5,101,9 + $083d,$083d,1,105,5,105,7 + $083e,$083f,1,112,5,112,7 + $0840,$0841,1,113,5,113,7 + $0842,$0844,1,120,5,120,7 + $0845,$0845,1,121,5,121,9 + $0846,$0846,1,122,5,122,9 + $0847,$0847,1,123,5,123,9 + $0848,$084a,1,126,5,126,7 + $084b,$084d,1,129,5,129,7 + $084e,$084e,1,130,5,130,9 + $084f,$084f,1,131,5,131,9 + $0850,$0850,1,132,5,132,9 + $0851,$0852,1,135,5,135,7 + $0853,$0854,1,137,5,137,7 + $0855,$0856,1,138,5,138,7 + $0857,$0858,1,139,5,139,7 + $0859,$0859,1,143,5,143,7 + + + + + + $0801,$0802,0,38,2,38,6 + $0803,$0804,0,39,5,39,9 + $0805,$0805,0,40,5,40,9 + $0806,$0809,0,41,2,41,6 + $080a,$080a,0,42,2,42,6 + $080b,$080c,0,44,5,44,9 + + + + + + $080d,$080e,1,23,5,23,7 + $080f,$0810,1,24,5,24,7 + $0811,$0813,1,28,5,28,7 + $0814,$0814,1,31,5,31,7 + $0815,$0816,1,38,5,38,7 + $0817,$0818,1,39,5,39,7 + $0819,$081a,1,46,5,46,7 + $081b,$081d,1,47,5,47,7 + $081e,$081f,1,50,5,50,7 + $0820,$0821,1,52,5,52,7 + $0822,$0823,1,53,5,53,7 + $0824,$0825,1,54,5,54,7 + $0826,$0826,1,58,5,58,7 + $0827,$0828,1,64,5,64,7 + $0829,$0829,1,68,5,68,7 + $082a,$082b,1,74,5,74,7 + $082c,$082e,1,75,5,75,7 + $082f,$082f,1,79,5,79,7 + $0830,$0832,1,85,5,85,7 + $0833,$0833,1,86,5,86,9 + $0834,$0834,1,87,5,87,9 + $0835,$0835,1,88,5,88,9 + $0836,$0836,1,92,5,92,7 + $0837,$0839,1,98,5,98,7 + $083a,$083a,1,99,5,99,9 + $083b,$083b,1,100,5,100,9 + $083c,$083c,1,101,5,101,9 + $083d,$083d,1,105,5,105,7 + $083e,$083f,1,112,5,112,7 + $0840,$0841,1,113,5,113,7 + $0842,$0844,1,120,5,120,7 + $0845,$0845,1,121,5,121,9 + $0846,$0846,1,122,5,122,9 + $0847,$0847,1,123,5,123,9 + $0848,$084a,1,126,5,126,7 + $084b,$084d,1,129,5,129,7 + $084e,$084e,1,130,5,130,9 + $084f,$084f,1,131,5,131,9 + $0850,$0850,1,132,5,132,9 + $0851,$0852,1,135,5,135,7 + $0853,$0854,1,137,5,137,7 + $0855,$0856,1,138,5,138,7 + $0857,$0858,1,139,5,139,7 + $0859,$0859,1,143,5,143,7 + + + + + + + + Basic,$0400,SCREEN,1,15,10,15,15 + Basic,$0003,val,1,16,10,16,12 + Code,$080d,__start,1,19,1,19,8 + Code,$0815,printother,1,34,1,34,11 + Code,$0002,i,1,35,12,35,12 + Code,$0819,__b1,1,43,3,43,7 + Code,$0827,incval,1,61,1,61,7 + Code,$082a,printval,1,71,1,71,9 + Code,$0830,ival,1,82,1,82,5 + Code,$0837,pval,1,95,1,95,5 + Code,$083e,main,1,108,1,108,5 + Code,$0004,i,1,109,12,109,12 + Code,$0842,__b1,1,117,3,117,7 + Basic,$080b,upstartEnd,0,43,1,43,11 + + + + + + + + + diff --git a/src/test/target/procedure-callingconvention-stack-far-3.klog b/src/test/target/procedure-callingconvention-stack-far-3.klog new file mode 100644 index 000000000..351cd59e1 --- /dev/null +++ b/src/test/target/procedure-callingconvention-stack-far-3.klog @@ -0,0 +1,22 @@ +Output dir: D:\Users\svenv\OneDrive\Documents\GitHub\kickc\src\test\target +parsing +flex pass 1 +flex pass 2 +flex pass 3 +Output pass +Writing prg file: procedure-callingconvention-stack-far-3.prg + +Memory Map +---------- +Program-segment: + +Basic-segment: + $0801-$080c Basic + +Code-segment: + $080d-$0859 Code + +Data-segment: + +Writing Vice symbol file: procedure-callingconvention-stack-far-3.vs +Writing Symbol file: procedure-callingconvention-stack-far-3.sym diff --git a/src/test/target/procedure-callingconvention-stack-far-3.prg b/src/test/target/procedure-callingconvention-stack-far-3.prg new file mode 100644 index 000000000..fe3b357ee Binary files /dev/null and b/src/test/target/procedure-callingconvention-stack-far-3.prg differ diff --git a/src/test/target/procedure-callingconvention-stack-far-3.sym b/src/test/target/procedure-callingconvention-stack-far-3.sym new file mode 100644 index 000000000..f1267c367 --- /dev/null +++ b/src/test/target/procedure-callingconvention-stack-far-3.sym @@ -0,0 +1,20 @@ +.label val=$3 +.label SCREEN=$400 +.label __start=$80d { +} +.label pval=$837 { +} +.label ival=$830 { +} +.label incval=$827 { +} +.label main=$83e { + .label __b1=$842 + .label i=$4 +} +.label printother=$815 { + .label __b1=$819 + .label i=$2 +} +.label printval=$82a { +} diff --git a/src/test/target/procedure-callingconvention-stack-far-3.vs b/src/test/target/procedure-callingconvention-stack-far-3.vs new file mode 100644 index 000000000..2787fc577 --- /dev/null +++ b/src/test/target/procedure-callingconvention-stack-far-3.vs @@ -0,0 +1,14 @@ +al C:3 .val +al C:819 .__b1__0 +al C:842 .__b1__1 +al C:400 .SCREEN +al C:80d .__start +al C:837 .pval +al C:2 .i__0 +al C:4 .i__1 +al C:830 .ival +al C:80b .upstartEnd +al C:827 .incval +al C:83e .main +al C:815 .printother +al C:82a .printval