diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java index 30afba97c..280c4811d 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java @@ -44,17 +44,21 @@ final public class AsmFragmentInstanceSpecBuilder { } /** - * Create a fragment instance spec factory for a subroutine call + * Create a fragment instance spec factory for a banked call * - * @param callingDistance The class expressing the distance of the call: "near", "close", "far" plus bankArea and bank information calculated from the from and to procedure. - * @param callingConvention The string expressing the calling convention supported by the fragment. - * @param procedureName The full name of the procedure. - * @param program The program + * @param callingConvention The calling convention + * @param proximity The calling distance of the call + * @param toBank The bank of the procedure being called + * @param procedureName The full name of the procedure being called. + * @param program The program * @return the fragment instance spec factory */ - public static AsmFragmentInstanceSpec callBanked(String callingConvention, Procedure.CallingProximity proximity, Bank toBank, String procedureName, Program program) { + public static AsmFragmentInstanceSpec callBanked(Procedure.CallingConvention callingConvention, Procedure.CallingProximity proximity, Bank toBank, String procedureName, Program program) { AsmFragmentBindings bindings = new AsmFragmentBindings(program); - AsmFragmentSignature signature = new AsmFragmentSignature.CallBanked(callingConvention, proximity, toBank); + AsmFragmentSignature signature = new AsmFragmentSignature.CallBanked( + callingConvention.getShortName(), + proximity.toString(), + (proximity.equals(Procedure.CallingProximity.NEAR)?null:toBank.bankArea())); ScopeRef codeScope = program.getScope().getRef(); bindings.bind("c1", new ConstantInteger(toBank.bankNumber())); 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 4b37b89a5..1a4a3f596 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java +++ b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java @@ -2,8 +2,6 @@ package dk.camelot64.kickc.fragment.signature; import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureLexer; import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureParser; -import dk.camelot64.kickc.model.symbols.Bank; -import dk.camelot64.kickc.model.symbols.Procedure; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -79,19 +77,19 @@ public interface AsmFragmentSignature { final private String callingConvention; - final private Procedure.CallingProximity proximity; + final private String proximity; - final private Bank toBank; + final private String toBankArea; - public CallBanked(String callingConvention, Procedure.CallingProximity proximity, Bank toBank) { + public CallBanked(String callingConvention, String proximity, String toBankArea) { this.callingConvention = callingConvention; this.proximity = proximity; - this.toBank = toBank; + this.toBankArea = toBankArea; } @Override public String getName() { - return "call_" + callingConvention.toLowerCase() + "_" + proximity.toString().toLowerCase() + (proximity.equals(Procedure.CallingProximity.NEAR)?"":("_"+toBank.bankArea())); + return "call_" + callingConvention + "_" + proximity + ((toBankArea==null)?"":("_"+toBankArea)); } } 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 4252fb9d6..ac2599c55 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java @@ -74,6 +74,7 @@ public class Procedure extends Scope { /** A trampoline bank change is needed. Caller and callee are different banks of the same banking area. */ FAR; + public static CallingProximity forCall(Bank from, Bank to) { if(to==null) { // NEAR: call to the common bank @@ -92,29 +93,42 @@ public class Procedure extends Scope { return FAR; } } + + @Override + public String toString() { + return name().toLowerCase(); + } + } /** The method for passing parameters and return value to the procedure. */ public enum CallingConvention { /** Parameters and return value handled through PHI-transitions. */ - PHI_CALL("__phicall"), + PHI_CALL("__phicall", "phi"), /** Parameters and return value over the stack. */ - STACK_CALL("__stackcall"), + STACK_CALL("__stackcall", "stack"), /** Parameters and return value handled through shared variables. */ - VAR_CALL("__varcall"), + VAR_CALL("__varcall", "var"), /** Intrinsic calling. Will be converted to intrinsic ASM late in the compile. */ - INTRINSIC_CALL("__intrinsiccall"); + INTRINSIC_CALL("__intrinsiccall", "intrinsic"); private final String name; - CallingConvention(String name) { + private final String shortName; + + CallingConvention(String name, String shortName) { this.name = name; + this.shortName = shortName; } public String getName() { return name; } + public String getShortName() { + return shortName; + } + /** Get a calling convention by name. */ public static CallingConvention getCallingConvension(String name) { for(CallingConvention value : CallingConvention.values()) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 2211d4fd1..81fefaad9 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -905,7 +905,7 @@ public class Pass4CodeGeneration { if(Procedure.CallingProximity.NEAR.equals(callingProximity)) { asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false); } else { - AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.callBanked("phi", callingProximity, toProcedure.getBank(), call.getProcedure().getFullName(), program), program); + AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.callBanked(Procedure.CallingConvention.PHI_CALL, callingProximity, toProcedure.getBank(), call.getProcedure().getFullName(), program), program); } } else if (Procedure.CallingConvention.STACK_CALL.equals(toProcedure.getCallingConvention())) { final Procedure.CallingProximity callingProximity = Procedure.CallingProximity.forCall(fromProcedure.getBank(), toProcedure.getBank());