mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-22 06:29:23 +00:00
far calls for __stackcall calling convention functions.
This commit is contained in:
parent
828e38a8b3
commit
4a4d6f72d0
@ -278,7 +278,7 @@ 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.
|
||||
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();
|
||||
|
@ -45,33 +45,35 @@ final public class AsmFragmentInstanceSpecBuilder {
|
||||
/**
|
||||
* Create a fragment instance spec factory for a far call entry
|
||||
*
|
||||
* @param call The statement call
|
||||
* @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(StatementCall call, Program program) {
|
||||
public static AsmFragmentInstanceSpec farCallEntry(Long bankFar, String procedureName, Program program) {
|
||||
AsmFragmentBindings bindings = new AsmFragmentBindings(program);
|
||||
AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(call.getBankFar(), program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.EntryExit.Entry);
|
||||
AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.EntryExit.Entry);
|
||||
ScopeRef codeScope = program.getScope().getRef();
|
||||
// ScopeRef codeScope = program.getStatementInfos().getBlock(call).getScope();
|
||||
bindings.bind("c1", new ConstantInteger(call.getBankFar()));
|
||||
bindings.bind("la1", new LabelRef(call.getProcedure().getFullName()));
|
||||
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 exit
|
||||
*
|
||||
* @param call The statement call
|
||||
* @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(StatementCall call, Program program) {
|
||||
public static AsmFragmentInstanceSpec farCallExit(Long bankFar, String procedureName, Program program) {
|
||||
AsmFragmentBindings bindings = new AsmFragmentBindings(program);
|
||||
AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(call.getBankFar(), program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.EntryExit.Exit);
|
||||
ScopeRef codeScope = program.getStatementInfos().getBlock(call).getScope();
|
||||
bindings.bind("la1", new LabelRef(codeScope.getFullName()));
|
||||
bindings.bind("la2", new ConstantInteger(call.getBankFar()));
|
||||
AsmFragmentSignature signature = new AsmFragmentSignature.CallFar(bankFar, program.getTargetPlatform().getName(), AsmFragmentSignature.CallFar.EntryExit.Exit);
|
||||
ScopeRef codeScope = program.getScope().getRef();
|
||||
bindings.bind("c1", new ConstantInteger(bankFar));
|
||||
bindings.bind("la1", new LabelRef(procedureName));
|
||||
return new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,15 @@ public class StatementCallExecute extends StatementBase implements StatementCall
|
||||
/** The calling convention to use. */
|
||||
private Procedure.CallingConvention callingConvention;
|
||||
|
||||
/** This contains the far call parameters */
|
||||
private Long bankFar;
|
||||
|
||||
public StatementCallExecute(SymbolTypeProcedure procedureType, RValue procedure, Procedure.CallingConvention callingConvention, StatementSource source, List<Comment> comments) {
|
||||
super(source, comments);
|
||||
this.procedureType = procedureType;
|
||||
this.procedure = procedure;
|
||||
this.callingConvention = callingConvention;
|
||||
this.bankFar = bankFar;
|
||||
}
|
||||
|
||||
public SymbolTypeProcedure getProcedureType() {
|
||||
|
@ -867,8 +867,8 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
if(procedure.isDeclaredFar()) {
|
||||
// Generate ASM for a call (in a bank or other)
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallEntry(call, program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallExit(call, program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallEntry(call.getBankFar(), call.getProcedure().getFullName(), program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallExit(call.getBankFar(), call.getProcedure().getFullName(), program), program);
|
||||
// asm.addInstruction("jsr far", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
|
||||
} else {
|
||||
asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
|
||||
@ -876,17 +876,23 @@ public class Pass4CodeGeneration {
|
||||
} else if (Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
if(procedure.isDeclaredFar()) {
|
||||
// Generate ASM for a far call (in a bank or other)
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallEntry(call, program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallExit(call, program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallEntry(call.getBankFar(), call.getProcedure().getFullName(), program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallExit(call.getBankFar(), call.getProcedure().getFullName(), program), program);
|
||||
} else {
|
||||
asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
|
||||
}
|
||||
}
|
||||
} else if (statement instanceof StatementCallExecute) {
|
||||
StatementCallExecute call = (StatementCallExecute) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
RValue procedureRVal = call.getProcedureRVal();
|
||||
// Generate ASM for a call
|
||||
if(procedure.isDeclaredFar()) {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallEntry(procedure.getBankFar(), call.getProcedure().getFullName(), program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.farCallExit(procedure.getBankFar(), call.getProcedure().getFullName(), program), program);
|
||||
} else {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
}
|
||||
if (!(procedureRVal instanceof ProcedureRef)) {
|
||||
asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL);
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
al C:400 .SCREEN
|
||||
al C:80b .upstartEnd
|
||||
al C:80d .main
|
||||
al C:819 .plus
|
||||
al C:37 .return
|
13
src/test/kc/procedure-callingconvention-phi-far-1.c
Normal file
13
src/test/kc/procedure-callingconvention-phi-far-1.c
Normal file
@ -0,0 +1,13 @@
|
||||
// Test a procedure with calling convention stack
|
||||
|
||||
char* const SCREEN = (char*)0x0400;
|
||||
|
||||
void main(void) {
|
||||
SCREEN[0] = plus('0', 7);
|
||||
}
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
|
||||
char __far(1) plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
Loading…
Reference in New Issue
Block a user