1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-01 16:51:12 +00:00

Refactored calling distance.

This commit is contained in:
jespergravgaard 2023-04-23 21:07:16 +02:00
parent eb69af8fe7
commit 8c7a144579
4 changed files with 27 additions and 29 deletions

View File

@ -46,22 +46,21 @@ final public class AsmFragmentInstanceSpecBuilder {
/** /**
* Create a fragment instance spec factory for a banked call * Create a fragment instance spec factory for a banked call
* *
* @param callingConvention The calling convention * @param toProcedure The procedure being called
* @param proximity The calling distance of the call * @param callingDistance 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 * @param program The program
* @return the fragment instance spec factory * @return the fragment instance spec factory
*/ */
public static AsmFragmentInstanceSpec callBanked(Procedure.CallingConvention callingConvention, Procedure.CallingProximity proximity, Bank toBank, String procedureName, Program program) { public static AsmFragmentInstanceSpec callBanked(Procedure toProcedure, Procedure.CallingDistance callingDistance, Program program) {
final Bank toBank = toProcedure.getBank();
AsmFragmentBindings bindings = new AsmFragmentBindings(program); AsmFragmentBindings bindings = new AsmFragmentBindings(program);
AsmFragmentSignature signature = new AsmFragmentSignature.CallBanked( AsmFragmentSignature signature = new AsmFragmentSignature.CallBanked(
callingConvention.getShortName(), toProcedure.getCallingConvention().getShortName(),
proximity.toString(), callingDistance.toString(),
(proximity.equals(Procedure.CallingProximity.NEAR)?null:toBank.bankArea())); (callingDistance.equals(Procedure.CallingDistance.NEAR)?null:toBank.bankArea()));
ScopeRef codeScope = program.getScope().getRef(); ScopeRef codeScope = program.getScope().getRef();
bindings.bind("c1", new ConstantInteger(toBank.bankNumber())); bindings.bind("c1", new ConstantInteger(toBank.bankNumber()));
bindings.bind("la1", new LabelRef(procedureName)); bindings.bind("la1", new LabelRef(toProcedure.getFullName()));
return new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); return new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
} }

View File

@ -77,19 +77,19 @@ public interface AsmFragmentSignature {
final private String callingConvention; final private String callingConvention;
final private String proximity; final private String callingDistance;
final private String toBankArea; final private String toBankArea;
public CallBanked(String callingConvention, String proximity, String toBankArea) { public CallBanked(String callingConvention, String callingDistance, String toBankArea) {
this.callingConvention = callingConvention; this.callingConvention = callingConvention;
this.proximity = proximity; this.callingDistance = callingDistance;
this.toBankArea = toBankArea; this.toBankArea = toBankArea;
} }
@Override @Override
public String getName() { public String getName() {
return "call_" + callingConvention + "_" + proximity + ((toBankArea==null)?"":("_"+toBankArea)); return "call_" + callingConvention + "_" + callingDistance + ((toBankArea==null)?"":("_"+toBankArea));
} }
} }

View File

@ -33,7 +33,7 @@ public class Procedure extends Scope {
private List<Comment> comments; private List<Comment> comments;
/** Reserved zeropage addresses. */ /** Reserved zeropage addresses. */
private List<Integer> reservedZps; private List<Integer> reservedZps;
/** The data and code segment to put the procedure into. When null the procedure is not assigned to the code segment. */ /** The code segment to put the procedure code into. When null the procedure is not assigned to the code segment. */
private String segmentCode; private String segmentCode;
/** The list of constructor procedures for this procedure. The constructor procedures are called during program initialization. */ /** The list of constructor procedures for this procedure. The constructor procedures are called during program initialization. */
private final List<ProcedureRef> constructorRefs; private final List<ProcedureRef> constructorRefs;
@ -43,7 +43,7 @@ public class Procedure extends Scope {
private StatementSource definitionSource; private StatementSource definitionSource;
/** /**
* The bank that the procedure code is placed in. * The bank that the procedure code is placed in.
* Used to decide whether to produce near, close or far call when generating code. * Used to decide whether to produce near, close or far call code when generating calls.
* If null, the procedure is in a common bank (always visible) and all calls will be near. * If null, the procedure is in a common bank (always visible) and all calls will be near.
*/ */
private Bank bank; private Bank bank;
@ -65,17 +65,16 @@ public class Procedure extends Scope {
this.bank = bank; this.bank = bank;
} }
/** The different distances between banked code, which will determine the type of call needed. */ /** The bank distance between a caller and callee, which will determine the type of call needed. */
public enum CallingProximity { public enum CallingDistance {
/** No bank change is needed. Caller and callee are both in the same bank or in the common bank. */ /** Caller and callee are both in the same bank or in the common bank. No bank change is needed. */
NEAR, NEAR,
/** A direct bank change is needed. Caller is in the common bank or a different banking area. */ /** Caller is in the common bank or a different banking area. A direct bank change is needed. */
CLOSE, CLOSE,
/** A trampoline bank change is needed. Caller and callee are different banks of the same banking area. */ /** Caller and callee are different banks of the same banking area. A trampoline bank change is needed. */
FAR; FAR;
public static CallingDistance forCall(Bank from, Bank to) {
public static CallingProximity forCall(Bank from, Bank to) {
if(to==null) { if(to==null) {
// NEAR: call to the common bank // NEAR: call to the common bank
return NEAR; return NEAR;

View File

@ -901,15 +901,15 @@ public class Pass4CodeGeneration {
genBlockPhiTransition(asm, block, callSuccessor, block.getScope()); genBlockPhiTransition(asm, block, callSuccessor, block.getScope());
} }
} }
final Procedure.CallingProximity callingProximity = Procedure.CallingProximity.forCall(fromProcedure.getBank(), toProcedure.getBank()); final Procedure.CallingDistance callingDistance = Procedure.CallingDistance.forCall(fromProcedure.getBank(), toProcedure.getBank());
if(Procedure.CallingProximity.NEAR.equals(callingProximity)) { if(Procedure.CallingDistance.NEAR.equals(callingDistance)) {
asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false); asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
} else { } else {
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.callBanked(Procedure.CallingConvention.PHI_CALL, callingProximity, toProcedure.getBank(), call.getProcedure().getFullName(), program), program); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.callBanked(toProcedure, callingDistance, program), program);
} }
} else if (Procedure.CallingConvention.STACK_CALL.equals(toProcedure.getCallingConvention())) { } else if (Procedure.CallingConvention.STACK_CALL.equals(toProcedure.getCallingConvention())) {
final Procedure.CallingProximity callingProximity = Procedure.CallingProximity.forCall(fromProcedure.getBank(), toProcedure.getBank()); final Procedure.CallingDistance callingDistance = Procedure.CallingDistance.forCall(fromProcedure.getBank(), toProcedure.getBank());
if(Procedure.CallingProximity.NEAR.equals(callingProximity)) { if(Procedure.CallingDistance.NEAR.equals(callingDistance)) {
asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false); asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
} else { } else {
throw new CompileError("Stack Call procedure not supported in banked mode " + toProcedure.toString(program)); throw new CompileError("Stack Call procedure not supported in banked mode " + toProcedure.toString(program));
@ -922,8 +922,8 @@ public class Pass4CodeGeneration {
ProgramScope scope = getScope(); ProgramScope scope = getScope();
Procedure toProcedure = scope.getProcedure(procedureRef); Procedure toProcedure = scope.getProcedure(procedureRef);
Procedure fromProcedure = block.getProcedure(this.program); Procedure fromProcedure = block.getProcedure(this.program);
final Procedure.CallingProximity callingProximity = Procedure.CallingProximity.forCall(fromProcedure.getBank(), toProcedure.getBank()); final Procedure.CallingDistance callingDistance = Procedure.CallingDistance.forCall(fromProcedure.getBank(), toProcedure.getBank());
if(Procedure.CallingProximity.NEAR.equals(callingProximity)) { if(Procedure.CallingDistance.NEAR.equals(callingDistance)) {
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
} else { } else {
throw new CompileError("Stack Call procedure not supported in banked mode " + toProcedure.toString(program)); throw new CompileError("Stack Call procedure not supported in banked mode " + toProcedure.toString(program));