mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-22 18:37:29 +00:00
- Mem[x] parameters in a banked function are always allocated in main memory.
- Mem[x] return value(s) in banked functions are always allocated in main memory. - Mem[x] intermediate value(s) in banked functions are always placed in the designated data segment. This to accommodate better banking logic for far function calls. (There might be more complexity for other type of variables, but for equinoxe it's working!). (cherry picked from commit 649a187d7e9290b630a951d8968ce5ece6ba2216)
This commit is contained in:
parent
b650ba99a9
commit
4706611564
@ -34,8 +34,8 @@ public class Procedure extends Scope {
|
||||
private List<Comment> comments;
|
||||
/** Reserved zeropage addresses. */
|
||||
private List<Integer> reservedZps;
|
||||
/** The code segment to put the procedure into. */
|
||||
private final String codeSegment;
|
||||
/** The data and code segment to put the procedure into. */
|
||||
private String segmentCode;
|
||||
/** The list of constructor procedures for this procedure. The constructor procedures are called during program initialization. */
|
||||
private final List<ProcedureRef> constructorRefs;
|
||||
/** Is this procedure declared as a constructor procedure. */
|
||||
@ -98,14 +98,15 @@ public class Procedure extends Scope {
|
||||
/** The calling convention used for this procedure. */
|
||||
private CallingConvention callingConvention;
|
||||
|
||||
public Procedure(String name, SymbolTypeProcedure procedureType, Scope parentScope, String codeSegment, String dataSegment, CallingConvention callingConvention, Bank bankLocation) {
|
||||
super(name, parentScope, dataSegment);
|
||||
public Procedure(String name, SymbolTypeProcedure procedureType, Scope parentScope, String segmentCode, String segmentData, CallingConvention callingConvention, Bank bankLocation) {
|
||||
super(name, parentScope, segmentData);
|
||||
this.procedureType = procedureType;
|
||||
this.declaredInline = false;
|
||||
this.bankLocation = bankLocation;
|
||||
this.interruptType = null;
|
||||
this.comments = new ArrayList<>();
|
||||
this.codeSegment = codeSegment;
|
||||
this.segmentCode = segmentCode;
|
||||
this.segmentData = segmentData; // The parameter dataSegment was foreseen, but never implemented.
|
||||
this.callingConvention = callingConvention;
|
||||
this.constructorRefs = new ArrayList<>();
|
||||
this.isConstructor = false;
|
||||
@ -127,8 +128,12 @@ public class Procedure extends Scope {
|
||||
this.callingConvention = callingConvention;
|
||||
}
|
||||
|
||||
public String getCodeSegment() {
|
||||
return codeSegment;
|
||||
public String getSegmentCode() {
|
||||
return segmentCode;
|
||||
}
|
||||
|
||||
public void setSegmentCode(String segmentCode) {
|
||||
this.segmentCode = segmentCode;
|
||||
}
|
||||
|
||||
public List<String> getParameterNames() {
|
||||
@ -339,13 +344,13 @@ public class Procedure extends Scope {
|
||||
Objects.equals(interruptType, procedure.interruptType) &&
|
||||
Objects.equals(comments, procedure.comments) &&
|
||||
Objects.equals(reservedZps, procedure.reservedZps) &&
|
||||
Objects.equals(codeSegment, procedure.codeSegment) &&
|
||||
Objects.equals(segmentCode, procedure.segmentCode) &&
|
||||
Objects.equals(constructorRefs, procedure.constructorRefs) &&
|
||||
callingConvention == procedure.callingConvention;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), procedureType, parameterNames, variableLengthParameterList, declaredInline, declaredIntrinsic, interruptType, comments, reservedZps, codeSegment, constructorRefs, isConstructor, callingConvention);
|
||||
return Objects.hash(super.hashCode(), procedureType, parameterNames, variableLengthParameterList, declaredInline, declaredIntrinsic, interruptType, comments, reservedZps, segmentCode, constructorRefs, isConstructor, callingConvention);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public abstract class Scope implements Symbol {
|
||||
private int blockCount = 1;
|
||||
private Scope parentScope;
|
||||
private String fullName;
|
||||
private String segmentData;
|
||||
protected String segmentData;
|
||||
|
||||
public Scope(String name, Scope parentScope, String segmentData) {
|
||||
this.name = name;
|
||||
@ -45,6 +45,10 @@ public abstract class Scope implements Symbol {
|
||||
return segmentData;
|
||||
}
|
||||
|
||||
public void setSegmentData(String segmentData) {
|
||||
this.segmentData = segmentData;
|
||||
}
|
||||
|
||||
public HashMap<String, Symbol> getSymbols() {
|
||||
return symbols;
|
||||
}
|
||||
|
@ -588,7 +588,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
parameterList.add(paramVar);
|
||||
}
|
||||
procedure.setParameters(parameterList);
|
||||
procedure.setCodeSegment(currentCodeSegment); // When a procedure is defined, the currentCodeSegment is to be set.
|
||||
procedure.setSegmentData(currentDataSegment); // When a procedure is defined, the currentDataSegment is to be set.
|
||||
procedure.setSegmentCode(currentCodeSegment); // When a procedure is defined, the currentCodeSegment is to be set.
|
||||
procedure.setBankLocation(currentBank); // When a procedure is defined, the currentBank is to be set, or far calls won't work.
|
||||
// Add return variable
|
||||
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
|
||||
|
@ -115,7 +115,7 @@ public class Pass4CodeGeneration {
|
||||
currentScope = block.getScope();
|
||||
if (block.isProcedureEntry(program)) {
|
||||
Procedure procedure = block.getProcedure(program);
|
||||
currentCodeSegmentName = procedure.getCodeSegment();
|
||||
currentCodeSegmentName = procedure.getSegmentCode();
|
||||
}
|
||||
setCurrentSegment(currentCodeSegmentName, asm);
|
||||
asm.startChunk(currentScope, null, block.getLabel().getFullName());
|
||||
@ -580,6 +580,31 @@ public class Pass4CodeGeneration {
|
||||
if (registerMainMem.getAddress() == null) {
|
||||
// Generate into the data segment
|
||||
// Set segment
|
||||
// We check first the bank of the variable. Only local variables can be stored in the bank.
|
||||
// Parameters must be stored in main memory.
|
||||
if(!variable.getDataSegment().equals("Data")) {
|
||||
if(scope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) scope;
|
||||
List<Variable> parameters = procedure.getParameters();
|
||||
if (variable.isKindPhiVersion()) {
|
||||
Variable master = variable.getPhiMaster();
|
||||
if (master != null) {
|
||||
if (parameters.contains(master) || master.getLocalName().equals("return")) {
|
||||
variable.setDataSegment("Data");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intermediate variables are placed at the banked data segment, but parameters and return values are kept untouched.
|
||||
if (variable.isKindIntermediate()) {
|
||||
if (scope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) scope;
|
||||
variable.setDataSegment(procedure.getSegmentData());
|
||||
}
|
||||
}
|
||||
setCurrentSegment(variable.getDataSegment(), asm);
|
||||
setCurrentSegment(variable.getDataSegment(), asm);
|
||||
// Add any comments
|
||||
generateComments(asm, variable.getComments());
|
||||
|
Loading…
x
Reference in New Issue
Block a user