Refactored calling convention.

This commit is contained in:
jespergravgaard 2023-04-23 20:54:22 +02:00
parent 9f3ca81e6a
commit eb69af8fe7
4 changed files with 36 additions and 20 deletions

View File

@ -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));

View File

@ -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));
}
}

View File

@ -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()) {

View File

@ -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());