mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-20 23:30:43 +00:00
Refactored calling convention.
This commit is contained in:
parent
9f3ca81e6a
commit
eb69af8fe7
@ -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));
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user