mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 19:50:10 +00:00
Renamed AsmSegment to AsmChunk in preparation for introduction of KickAsm segments. #113
This commit is contained in:
parent
31a3bd9078
commit
fe93a48360
@ -12,49 +12,49 @@ import java.util.ListIterator;
|
|||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A segment of an ASM program. The segment has a number of methods/attributes that describe the lines of the segment.
|
* A chunk of an ASM program. The chunk has a number of methods/attributes that describe the lines of the chunk.
|
||||||
* Typically each ICL statement becomes a single ASM segment through the AsmFragment subsystem.
|
* Typically each ICL statement becomes a single ASM chunk through the AsmFragment subsystem.
|
||||||
*/
|
*/
|
||||||
public class AsmSegment {
|
public class AsmChunk {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The lines of the segment.
|
* The lines of the chunk.
|
||||||
*/
|
*/
|
||||||
private List<AsmLine> lines;
|
private List<AsmLine> lines;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index of the segment.
|
* Index of the chunk.
|
||||||
*/
|
*/
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index of the ICL statement that the segment is generated from,
|
* Index of the ICL statement that the chunk is generated from,
|
||||||
*/
|
*/
|
||||||
private Integer statementIdx;
|
private Integer statementIdx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Readable name of the ICL source of the segment.
|
* Readable name of the ICL source of the chunk.
|
||||||
*/
|
*/
|
||||||
private String source;
|
private String source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Readable name of the fragment used to generate the segment.
|
* Readable name of the fragment used to generate the chunk.
|
||||||
*/
|
*/
|
||||||
private String fragment;
|
private String fragment;
|
||||||
|
|
||||||
/** If the segment represents a PHI transition (See. {@link PhiTransitions}) this contains the transition ID. */
|
/** If the chunk represents a PHI transition (See. {@link PhiTransitions}) this contains the transition ID. */
|
||||||
private String phiTransitionId;
|
private String phiTransitionId;
|
||||||
|
|
||||||
/** If the segment is an assignment in a PHI transition this contains the index of the assignment within the transition. */
|
/** If the chunk is an assignment in a PHI transition this contains the index of the assignment within the transition. */
|
||||||
private Integer phiTransitionAssignmentIdx;
|
private Integer phiTransitionAssignmentIdx;
|
||||||
|
|
||||||
/** The full name of the containing scope (procedure). */
|
/** The full name of the containing scope (procedure). */
|
||||||
private String scopeLabel;
|
private String scopeLabel;
|
||||||
|
|
||||||
/** If non-null this overwrites the clobber of the segment that is calculated by examining the ASM instruction lines. */
|
/** If non-null this overwrites the clobber of the chunk that is calculated by examining the ASM instruction lines. */
|
||||||
private AsmClobber clobberOverwrite;
|
private AsmClobber clobberOverwrite;
|
||||||
|
|
||||||
public AsmSegment(int index, ScopeRef scope, Integer statementIdx, String source) {
|
public AsmChunk(int index, ScopeRef scope, Integer statementIdx, String source) {
|
||||||
this.lines = new ArrayList<>();
|
this.lines = new ArrayList<>();
|
||||||
this.scopeLabel = scope.getFullName();
|
this.scopeLabel = scope.getFullName();
|
||||||
this.index = index;
|
this.index = index;
|
||||||
@ -133,8 +133,8 @@ public class AsmSegment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of bytes the segment occupies in memory.
|
* Get the number of bytes the chunk occupies in memory.
|
||||||
* Per default calculated by adding up the bytes of each ASM line in the segment.
|
* Per default calculated by adding up the bytes of each ASM line in the chunk.
|
||||||
*
|
*
|
||||||
* @return The number of bytes
|
* @return The number of bytes
|
||||||
*/
|
*/
|
||||||
@ -147,8 +147,8 @@ public class AsmSegment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of cycles it takes to execute the segment
|
* Get the number of cycles it takes to execute the chunk
|
||||||
* Per default calculated by adding up the cycles of each ASM line in the segment.
|
* Per default calculated by adding up the cycles of each ASM line in the chunk.
|
||||||
*
|
*
|
||||||
* @return The number of cycles
|
* @return The number of cycles
|
||||||
*/
|
*/
|
||||||
@ -161,8 +161,8 @@ public class AsmSegment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the registers clobbered when executing the segment
|
* Get the registers clobbered when executing the chunk
|
||||||
* Per default calculated by adding up the clobber of each ASM line in the segment.
|
* Per default calculated by adding up the clobber of each ASM line in the chunk.
|
||||||
*
|
*
|
||||||
* @return The registers clobbered
|
* @return The registers clobbered
|
||||||
*/
|
*/
|
||||||
@ -186,7 +186,7 @@ public class AsmSegment {
|
|||||||
* Get ASM line by index
|
* Get ASM line by index
|
||||||
*
|
*
|
||||||
* @param idx The index of the line to get
|
* @param idx The index of the line to get
|
||||||
* @return The line with the passed index. Null if not found inside the segment.
|
* @return The line with the passed index. Null if not found inside the chunk.
|
||||||
*/
|
*/
|
||||||
public AsmLine getAsmLine(int idx) {
|
public AsmLine getAsmLine(int idx) {
|
||||||
for(AsmLine asmLine : getLines()) {
|
for(AsmLine asmLine : getLines()) {
|
||||||
@ -246,7 +246,7 @@ public class AsmSegment {
|
|||||||
}
|
}
|
||||||
if(printState.isSourceIclInfo()) {
|
if(printState.isSourceIclInfo()) {
|
||||||
out.append(printState.getIndent()).append(" //");
|
out.append(printState.getIndent()).append(" //");
|
||||||
if(printState.isSourceSegmentIdInfo()) {
|
if(printState.isSourceChunkIdInfo()) {
|
||||||
out.append("SEG").append(getIndex());
|
out.append("SEG").append(getIndex());
|
||||||
}
|
}
|
||||||
if(source != null) {
|
if(source != null) {
|
@ -14,14 +14,14 @@ import java.util.List;
|
|||||||
public class AsmProgram {
|
public class AsmProgram {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The segments of the program. The segments hold the ASM lines.
|
* The chunks of the program. The chunks hold the ASM lines.
|
||||||
*/
|
*/
|
||||||
private List<AsmSegment> segments;
|
private List<AsmChunk> chunks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of the next segment.
|
* The index of the next chunk.
|
||||||
*/
|
*/
|
||||||
private int nextSegmentIndex;
|
private int nextChunkIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of the next line.
|
* The index of the next line.
|
||||||
@ -29,28 +29,28 @@ public class AsmProgram {
|
|||||||
private int nextLineIndex;
|
private int nextLineIndex;
|
||||||
|
|
||||||
public AsmProgram() {
|
public AsmProgram() {
|
||||||
this.segments = new ArrayList<>();
|
this.chunks = new ArrayList<>();
|
||||||
this.nextLineIndex = 0;
|
this.nextLineIndex = 0;
|
||||||
this.nextSegmentIndex = 0;
|
this.nextChunkIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<AsmSegment> getSegments() {
|
public Collection<AsmChunk> getChunks() {
|
||||||
return segments;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsmSegment startSegment(ScopeRef scopeRef, Integer statementIndex, String source) {
|
public AsmChunk startChunk(ScopeRef scopeRef, Integer statementIndex, String source) {
|
||||||
AsmSegment segment = new AsmSegment(nextSegmentIndex++, scopeRef, statementIndex, source);
|
AsmChunk chunk = new AsmChunk(nextChunkIndex++, scopeRef, statementIndex, source);
|
||||||
segments.add(segment);
|
chunks.add(chunk);
|
||||||
return segment;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsmSegment getCurrentSegment() {
|
public AsmChunk getCurrentChunk() {
|
||||||
return segments.get(segments.size() - 1);
|
return chunks.get(chunks.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLine(AsmLine line) {
|
public void addLine(AsmLine line) {
|
||||||
line.setIndex(nextLineIndex++);
|
line.setIndex(nextLineIndex++);
|
||||||
getCurrentSegment().addLine(line);
|
getCurrentChunk().addLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addComment(String comment, boolean isBlock) {
|
public void addComment(String comment, boolean isBlock) {
|
||||||
@ -236,51 +236,51 @@ public class AsmProgram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of bytes the segment occupies in memory.
|
* Get the number of bytes the program occupies in memory.
|
||||||
* Calculated by adding up the bytes of each ASM segment in the program.
|
* Calculated by adding up the bytes of each ASM chunk in the program.
|
||||||
*
|
*
|
||||||
* @return The number of bytes
|
* @return The number of bytes
|
||||||
*/
|
*/
|
||||||
public int getBytes() {
|
public int getBytes() {
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
for(AsmSegment segment : segments) {
|
for(AsmChunk chunk : chunks) {
|
||||||
bytes += segment.getBytes();
|
bytes += chunk.getBytes();
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of cycles it takes to execute the segment
|
* Get the number of cycles it takes to execute the program
|
||||||
* Calculated by adding up the cycles of each ASM segments in the program.
|
* Calculated by adding up the cycles of each ASM chunks in the program.
|
||||||
*
|
*
|
||||||
* @return The number of cycles
|
* @return The number of cycles
|
||||||
*/
|
*/
|
||||||
public double getCycles() {
|
public double getCycles() {
|
||||||
double cycles = 0.0;
|
double cycles = 0.0;
|
||||||
for(AsmSegment segment : segments) {
|
for(AsmChunk chunk : chunks) {
|
||||||
cycles += segment.getCycles();
|
cycles += chunk.getCycles();
|
||||||
}
|
}
|
||||||
return cycles;
|
return cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the CPU registers clobbered by the instructions of the fragment
|
* Get the CPU registers clobbered by the instructions of the program
|
||||||
*
|
*
|
||||||
* @return The clobbered registers
|
* @return The clobbered registers
|
||||||
*/
|
*/
|
||||||
public AsmClobber getClobber() {
|
public AsmClobber getClobber() {
|
||||||
AsmClobber clobber = new AsmClobber();
|
AsmClobber clobber = new AsmClobber();
|
||||||
for(AsmSegment segment : segments) {
|
for(AsmChunk chunk : chunks) {
|
||||||
clobber.add(segment.getClobber());
|
clobber.add(chunk.getClobber());
|
||||||
}
|
}
|
||||||
return clobber;
|
return clobber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(AsmPrintState printState, Program program) {
|
public String toString(AsmPrintState printState, Program program) {
|
||||||
StringBuilder out = new StringBuilder();
|
StringBuilder out = new StringBuilder();
|
||||||
for(AsmSegment segment : segments) {
|
for(AsmChunk chunk : chunks) {
|
||||||
out.append(segment.toString(printState, program));
|
out.append(chunk.toString(printState, program));
|
||||||
}
|
}
|
||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
@ -300,16 +300,16 @@ public class AsmProgram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ASM segment by line index
|
* Get ASM chunk by line index
|
||||||
*
|
*
|
||||||
* @param idx The index of the line to get the segment for
|
* @param idx The index of the line to get the chunk for
|
||||||
* @return The segment with the line that has the passed index. Null if not found
|
* @return The chunk with the line that has the passed index. Null if not found
|
||||||
*/
|
*/
|
||||||
public AsmSegment getAsmSegment(int idx) {
|
public AsmChunk getAsmChunk(int idx) {
|
||||||
for(AsmSegment segment : segments) {
|
for(AsmChunk chunk : chunks) {
|
||||||
for(AsmLine asmLine : segment.getLines()) {
|
for(AsmLine asmLine : chunk.getLines()) {
|
||||||
if(asmLine.getIndex() == idx) {
|
if(asmLine.getIndex() == idx) {
|
||||||
return segment;
|
return chunk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,8 +323,8 @@ public class AsmProgram {
|
|||||||
private boolean sourceCodeInfo;
|
private boolean sourceCodeInfo;
|
||||||
// Output comments with ICL-code and the ASM fragment name
|
// Output comments with ICL-code and the ASM fragment name
|
||||||
private boolean sourceIclInfo;
|
private boolean sourceIclInfo;
|
||||||
// Output segment ID in the ICL-comment
|
// Output chunk ID in the ICL-comment
|
||||||
private boolean sourceSegmentIdInfo;
|
private boolean sourceChunkIdInfo;
|
||||||
// Output ASM line numbers
|
// Output ASM line numbers
|
||||||
private boolean asmLineNumber;
|
private boolean asmLineNumber;
|
||||||
// Current indent - used during printing
|
// Current indent - used during printing
|
||||||
@ -366,12 +366,12 @@ public class AsmProgram {
|
|||||||
return sourceIclInfo;
|
return sourceIclInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSourceSegmentIdInfo() {
|
public boolean isSourceChunkIdInfo() {
|
||||||
return sourceSegmentIdInfo;
|
return sourceChunkIdInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSourceSegmentIdInfo(boolean sourceSegmentIdInfo) {
|
public void setSourceChunkIdInfo(boolean sourceChunkIdInfo) {
|
||||||
this.sourceSegmentIdInfo = sourceSegmentIdInfo;
|
this.sourceChunkIdInfo = sourceChunkIdInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSourceIclInfo(boolean sourceIclInfo) {
|
public void setSourceIclInfo(boolean sourceIclInfo) {
|
||||||
|
@ -65,8 +65,8 @@ public class AsmProgramStaticRegisterValues {
|
|||||||
|
|
||||||
private void initValues() {
|
private void initValues() {
|
||||||
AsmRegisterValues current = new AsmRegisterValues();
|
AsmRegisterValues current = new AsmRegisterValues();
|
||||||
for(AsmSegment segment : program.getSegments()) {
|
for(AsmChunk chunk : program.getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
current = updateStaticRegisterValues(current, line);
|
current = updateStaticRegisterValues(current, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public class AsmFragmentTemplate {
|
|||||||
AsmFragmentInstance fragmentInstance =
|
AsmFragmentInstance fragmentInstance =
|
||||||
new AsmFragmentInstance(new Program(), signature, ScopeRef.ROOT, this, bindings);
|
new AsmFragmentInstance(new Program(), signature, ScopeRef.ROOT, this, bindings);
|
||||||
AsmProgram asm = new AsmProgram();
|
AsmProgram asm = new AsmProgram();
|
||||||
asm.startSegment(ScopeRef.ROOT, null, signature);
|
asm.startChunk(ScopeRef.ROOT, null, signature);
|
||||||
fragmentInstance.generate(asm);
|
fragmentInstance.generate(asm);
|
||||||
AsmClobber asmClobber = asm.getClobber();
|
AsmClobber asmClobber = asm.getClobber();
|
||||||
this.clobber = new AsmFragmentClobber(asmClobber);
|
this.clobber = new AsmFragmentClobber(asmClobber);
|
||||||
|
@ -2,9 +2,8 @@ package dk.camelot64.kickc.passes;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.asm.AsmClobber;
|
import dk.camelot64.kickc.asm.AsmClobber;
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.asm.AsmSegment;
|
import dk.camelot64.kickc.asm.AsmChunk;
|
||||||
import dk.camelot64.kickc.model.*;
|
import dk.camelot64.kickc.model.*;
|
||||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
|
||||||
import dk.camelot64.kickc.model.values.LabelRef;
|
import dk.camelot64.kickc.model.values.LabelRef;
|
||||||
import dk.camelot64.kickc.model.values.RValue;
|
import dk.camelot64.kickc.model.values.RValue;
|
||||||
import dk.camelot64.kickc.model.values.VariableRef;
|
import dk.camelot64.kickc.model.values.VariableRef;
|
||||||
@ -61,23 +60,23 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
|||||||
|
|
||||||
AsmProgram asm = getProgram().getAsm();
|
AsmProgram asm = getProgram().getAsm();
|
||||||
boolean clobberProblem = false;
|
boolean clobberProblem = false;
|
||||||
for(AsmSegment asmSegment : asm.getSegments()) {
|
for(AsmChunk asmChunk : asm.getChunks()) {
|
||||||
if(asmSegment.getStatementIdx() != null) {
|
if(asmChunk.getStatementIdx() != null) {
|
||||||
// Find the ICL statement
|
// Find the ICL statement
|
||||||
int statementIdx = asmSegment.getStatementIdx();
|
int statementIdx = asmChunk.getStatementIdx();
|
||||||
Statement statement = getProgram().getStatementInfos().getStatement(statementIdx);
|
Statement statement = getProgram().getStatementInfos().getStatement(statementIdx);
|
||||||
// Find the registered clobbered by the ASM asmSegment
|
// Find the registered clobbered by the ASM asmChunk
|
||||||
AsmClobber asmSegmentClobber = asmSegment.getClobber();
|
AsmClobber asmChunkClobber = asmChunk.getClobber();
|
||||||
Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
|
Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmChunkClobber);
|
||||||
// Find vars assigned to in the statement
|
// Find vars assigned to in the statement
|
||||||
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
|
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
|
||||||
|
|
||||||
// Find alive variables
|
// Find alive variables
|
||||||
List<VariableRef> aliveVars = new ArrayList<>(getProgram().getLiveRangeVariablesEffective().getAliveEffective(statement));
|
List<VariableRef> aliveVars = new ArrayList<>(getProgram().getLiveRangeVariablesEffective().getAliveEffective(statement));
|
||||||
// If the segment is an assignment in a phi transition, examine the later phi transition assignments and update alive variables alive and variables assigned
|
// If the chunk is an assignment in a phi transition, examine the later phi transition assignments and update alive variables alive and variables assigned
|
||||||
if(asmSegment.getPhiTransitionId() != null && asmSegment.getPhiTransitionAssignmentIdx() != null) {
|
if(asmChunk.getPhiTransitionId() != null && asmChunk.getPhiTransitionAssignmentIdx() != null) {
|
||||||
String phiTransitionId = asmSegment.getPhiTransitionId();
|
String phiTransitionId = asmChunk.getPhiTransitionId();
|
||||||
int transitionAssignmentIdx = asmSegment.getPhiTransitionAssignmentIdx();
|
int transitionAssignmentIdx = asmChunk.getPhiTransitionAssignmentIdx();
|
||||||
ControlFlowBlock statementBlock = getProgram().getStatementInfos().getBlock(statementIdx);
|
ControlFlowBlock statementBlock = getProgram().getStatementInfos().getBlock(statementIdx);
|
||||||
Map<LabelRef, PhiTransitions> programPhiTransitions = getProgram().getPhiTransitions();
|
Map<LabelRef, PhiTransitions> programPhiTransitions = getProgram().getPhiTransitions();
|
||||||
PhiTransitions phiTransitions = programPhiTransitions.get(statementBlock.getLabel());
|
PhiTransitions phiTransitions = programPhiTransitions.get(statementBlock.getLabel());
|
||||||
|
@ -74,7 +74,7 @@ public class Pass4CodeGeneration {
|
|||||||
ScopeRef currentScope = ScopeRef.ROOT;
|
ScopeRef currentScope = ScopeRef.ROOT;
|
||||||
|
|
||||||
// Add file level comments
|
// Add file level comments
|
||||||
asm.startSegment(currentScope, null, "File Comments");
|
asm.startChunk(currentScope, null, "File Comments");
|
||||||
generateComments(asm, program.getFileComments());
|
generateComments(asm, program.getFileComments());
|
||||||
|
|
||||||
Number programPc;
|
Number programPc;
|
||||||
@ -88,7 +88,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asm.startSegment(currentScope, null, "Upstart");
|
asm.startChunk(currentScope, null, "Upstart");
|
||||||
if(TargetPlatform.C64BASIC.equals(program.getTargetPlatform())) {
|
if(TargetPlatform.C64BASIC.equals(program.getTargetPlatform())) {
|
||||||
asm.addLine(new AsmSetPc("Basic", AsmFormat.getAsmNumber(0x0801)));
|
asm.addLine(new AsmSetPc("Basic", AsmFormat.getAsmNumber(0x0801)));
|
||||||
asm.addLine(new AsmBasicUpstart("bbegin"));
|
asm.addLine(new AsmBasicUpstart("bbegin"));
|
||||||
@ -96,7 +96,7 @@ public class Pass4CodeGeneration {
|
|||||||
asm.addLine(new AsmSetPc("Program", AsmFormat.getAsmNumber(programPc)));
|
asm.addLine(new AsmSetPc("Program", AsmFormat.getAsmNumber(programPc)));
|
||||||
|
|
||||||
// Generate global ZP labels
|
// Generate global ZP labels
|
||||||
asm.startSegment(currentScope, null, "Global Constants & labels");
|
asm.startChunk(currentScope, null, "Global Constants & labels");
|
||||||
addConstants(asm, currentScope);
|
addConstants(asm, currentScope);
|
||||||
addZpLabels(asm, currentScope);
|
addZpLabels(asm, currentScope);
|
||||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||||
@ -104,7 +104,7 @@ public class Pass4CodeGeneration {
|
|||||||
// The current block is in a different scope. End the old scope.
|
// The current block is in a different scope. End the old scope.
|
||||||
generateScopeEnding(asm, currentScope);
|
generateScopeEnding(asm, currentScope);
|
||||||
currentScope = block.getScope();
|
currentScope = block.getScope();
|
||||||
asm.startSegment(currentScope, null, block.getLabel().getFullName());
|
asm.startChunk(currentScope, null, block.getLabel().getFullName());
|
||||||
// Add any procedure comments
|
// Add any procedure comments
|
||||||
if(block.isProcedureEntry(program)) {
|
if(block.isProcedureEntry(program)) {
|
||||||
Procedure procedure = block.getProcedure(program);
|
Procedure procedure = block.getProcedure(program);
|
||||||
@ -132,7 +132,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Generate label for block inside procedure
|
// Generate label for block inside procedure
|
||||||
asm.startSegment(currentScope, null, block.getLabel().getFullName());
|
asm.startChunk(currentScope, null, block.getLabel().getFullName());
|
||||||
asm.addLabel(block.getLabel().getLocalName().replace('@', 'b').replace(':', '_'));
|
asm.addLabel(block.getLabel().getLocalName().replace('@', 'b').replace(':', '_'));
|
||||||
}
|
}
|
||||||
// Generate statements
|
// Generate statements
|
||||||
@ -159,7 +159,7 @@ public class Pass4CodeGeneration {
|
|||||||
generateScopeEnding(asm, currentScope);
|
generateScopeEnding(asm, currentScope);
|
||||||
|
|
||||||
currentScope = ScopeRef.ROOT;
|
currentScope = ScopeRef.ROOT;
|
||||||
asm.startSegment(currentScope, null, "File Data");
|
asm.startChunk(currentScope, null, "File Data");
|
||||||
addData(asm, ScopeRef.ROOT);
|
addData(asm, ScopeRef.ROOT);
|
||||||
// Add all absolutely placed inline KickAsm
|
// Add all absolutely placed inline KickAsm
|
||||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||||
@ -168,11 +168,11 @@ public class Pass4CodeGeneration {
|
|||||||
StatementKickAsm statementKasm = (StatementKickAsm) statement;
|
StatementKickAsm statementKasm = (StatementKickAsm) statement;
|
||||||
if(statementKasm.getLocation() != null) {
|
if(statementKasm.getLocation() != null) {
|
||||||
String asmLocation = AsmFormat.getAsmConstant(program, (ConstantValue) statementKasm.getLocation(), 99, ScopeRef.ROOT);
|
String asmLocation = AsmFormat.getAsmConstant(program, (ConstantValue) statementKasm.getLocation(), 99, ScopeRef.ROOT);
|
||||||
String segmentName = "Inline";
|
String chunkName = "Inline";
|
||||||
if(asmLocation.matches("[a-zA-Z_][a-zA-Z0-9_]*")) {
|
if(asmLocation.matches("[a-zA-Z_][a-zA-Z0-9_]*")) {
|
||||||
segmentName = asmLocation;
|
chunkName = asmLocation;
|
||||||
}
|
}
|
||||||
asm.addLine(new AsmSetPc(segmentName, asmLocation));
|
asm.addLine(new AsmSetPc(chunkName, asmLocation));
|
||||||
addKickAsm(asm, statementKasm);
|
addKickAsm(asm, statementKasm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,7 +606,7 @@ public class Pass4CodeGeneration {
|
|||||||
public void generateStatementAsm(AsmProgram asm, ControlFlowBlock block, Statement statement, AsmCodegenAluState
|
public void generateStatementAsm(AsmProgram asm, ControlFlowBlock block, Statement statement, AsmCodegenAluState
|
||||||
aluState, boolean genCallPhiEntry) {
|
aluState, boolean genCallPhiEntry) {
|
||||||
|
|
||||||
asm.startSegment(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo));
|
asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo));
|
||||||
generateComments(asm, statement.getComments());
|
generateComments(asm, statement.getComments());
|
||||||
// IF the previous statement was added to the ALU register - generate the composite ASM fragment
|
// IF the previous statement was added to the ALU register - generate the composite ASM fragment
|
||||||
if(aluState.hasAluAssignment()) {
|
if(aluState.hasAluAssignment()) {
|
||||||
@ -680,16 +680,16 @@ public class Pass4CodeGeneration {
|
|||||||
HashMap<String, Value> bindings = new HashMap<>();
|
HashMap<String, Value> bindings = new HashMap<>();
|
||||||
AsmFragmentInstance asmFragmentInstance = new AsmFragmentInstance(program, "inline", block.getScope(), new AsmFragmentTemplate(statementAsm.getAsmLines()), bindings);
|
AsmFragmentInstance asmFragmentInstance = new AsmFragmentInstance(program, "inline", block.getScope(), new AsmFragmentTemplate(statementAsm.getAsmLines()), bindings);
|
||||||
asmFragmentInstance.generate(asm);
|
asmFragmentInstance.generate(asm);
|
||||||
AsmSegment currentSegment = asm.getCurrentSegment();
|
AsmChunk currentChunk = asm.getCurrentChunk();
|
||||||
|
|
||||||
if(statementAsm.getDeclaredClobber() != null) {
|
if(statementAsm.getDeclaredClobber() != null) {
|
||||||
currentSegment.setClobberOverwrite(statementAsm.getDeclaredClobber());
|
currentChunk.setClobberOverwrite(statementAsm.getDeclaredClobber());
|
||||||
} else {
|
} else {
|
||||||
for(AsmLine asmLine : currentSegment.getLines()) {
|
for(AsmLine asmLine : currentChunk.getLines()) {
|
||||||
if(asmLine instanceof AsmInstruction) {
|
if(asmLine instanceof AsmInstruction) {
|
||||||
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
|
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
|
||||||
if(asmInstruction.getType().getMnemnonic().equals("jsr")) {
|
if(asmInstruction.getType().getMnemnonic().equals("jsr")) {
|
||||||
currentSegment.setClobberOverwrite(AsmClobber.CLOBBER_ALL);
|
currentChunk.setClobberOverwrite(AsmClobber.CLOBBER_ALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ public class Pass4CodeGeneration {
|
|||||||
addKickAsm(asm, statementKasm);
|
addKickAsm(asm, statementKasm);
|
||||||
}
|
}
|
||||||
if(statementKasm.getDeclaredClobber() != null) {
|
if(statementKasm.getDeclaredClobber() != null) {
|
||||||
asm.getCurrentSegment().setClobberOverwrite(statementKasm.getDeclaredClobber());
|
asm.getCurrentChunk().setClobberOverwrite(statementKasm.getDeclaredClobber());
|
||||||
}
|
}
|
||||||
} else if(statement instanceof StatementCallPointer) {
|
} else if(statement instanceof StatementCallPointer) {
|
||||||
StatementCallPointer callPointer = (StatementCallPointer) statement;
|
StatementCallPointer callPointer = (StatementCallPointer) statement;
|
||||||
@ -738,7 +738,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(supported) {
|
if(supported) {
|
||||||
asm.getCurrentSegment().setClobberOverwrite(AsmClobber.CLOBBER_ALL);
|
asm.getCurrentChunk().setClobberOverwrite(AsmClobber.CLOBBER_ALL);
|
||||||
}
|
}
|
||||||
if(!supported) {
|
if(!supported) {
|
||||||
throw new RuntimeException("Call Pointer not supported " + statement);
|
throw new RuntimeException("Call Pointer not supported " + statement);
|
||||||
@ -778,7 +778,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asm.getCurrentSegment().setFragment(asmFragmentInstance.getFragmentName());
|
asm.getCurrentChunk().setFragment(asmFragmentInstance.getFragmentName());
|
||||||
asmFragmentInstance.generate(asm);
|
asmFragmentInstance.generate(asm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,8 +790,8 @@ public class Pass4CodeGeneration {
|
|||||||
*/
|
*/
|
||||||
private void generateInterruptEntry(AsmProgram asm, Procedure procedure) {
|
private void generateInterruptEntry(AsmProgram asm, Procedure procedure) {
|
||||||
Procedure.InterruptType interruptType = procedure.getInterruptType();
|
Procedure.InterruptType interruptType = procedure.getInterruptType();
|
||||||
asm.startSegment(procedure.getRef(), null, "entry interrupt(" + interruptType.name() + ")");
|
asm.startChunk(procedure.getRef(), null, "entry interrupt(" + interruptType.name() + ")");
|
||||||
//asm.getCurrentSegment().setXXX();
|
//asm.getCurrentChunk().setXXX();
|
||||||
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
|
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
|
||||||
// No entry ASM needed
|
// No entry ASM needed
|
||||||
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
|
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
|
||||||
@ -819,7 +819,7 @@ public class Pass4CodeGeneration {
|
|||||||
* @param interruptType The type of interrupt to generate
|
* @param interruptType The type of interrupt to generate
|
||||||
*/
|
*/
|
||||||
private void generateInterruptExit(AsmProgram asm, Statement statement, Procedure.InterruptType interruptType) {
|
private void generateInterruptExit(AsmProgram asm, Statement statement, Procedure.InterruptType interruptType) {
|
||||||
asm.getCurrentSegment().setSource(asm.getCurrentSegment().getSource() + " - exit interrupt(" + interruptType.name() + ")");
|
asm.getCurrentChunk().setSource(asm.getCurrentChunk().getSource() + " - exit interrupt(" + interruptType.name() + ")");
|
||||||
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
|
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
|
||||||
asm.addInstruction("jmp", AsmAddressingMode.ABS, "$ea81", false);
|
asm.addInstruction("jmp", AsmAddressingMode.ABS, "$ea81", false);
|
||||||
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
|
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
|
||||||
@ -898,13 +898,13 @@ public class Pass4CodeGeneration {
|
|||||||
PhiTransitions.PhiTransition transition = transitions.getTransition(fromBlock);
|
PhiTransitions.PhiTransition transition = transitions.getTransition(fromBlock);
|
||||||
if(!transitionIsGenerated(transition)) {
|
if(!transitionIsGenerated(transition)) {
|
||||||
Statement toFirstStatement = toBlock.getStatements().get(0);
|
Statement toFirstStatement = toBlock.getStatements().get(0);
|
||||||
String segmentSrc = "[" + toFirstStatement.getIndex() + "] phi from ";
|
String chunkSrc = "[" + toFirstStatement.getIndex() + "] phi from ";
|
||||||
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
|
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
|
||||||
segmentSrc += fBlock.getLabel().getFullName() + " ";
|
chunkSrc += fBlock.getLabel().getFullName() + " ";
|
||||||
}
|
}
|
||||||
segmentSrc += "to " + toBlock.getLabel().getFullName();
|
chunkSrc += "to " + toBlock.getLabel().getFullName();
|
||||||
asm.startSegment(scope, toFirstStatement.getIndex(), segmentSrc);
|
asm.startChunk(scope, toFirstStatement.getIndex(), chunkSrc);
|
||||||
asm.getCurrentSegment().setPhiTransitionId(transition.getTransitionId());
|
asm.getCurrentChunk().setPhiTransitionId(transition.getTransitionId());
|
||||||
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
|
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
|
||||||
asm.addLabel((toBlock.getLabel().getLocalName() + "_from_" + fBlock.getLabel().getLocalName()).replace('@', 'b').replace(':', '_'));
|
asm.addLabel((toBlock.getLabel().getLocalName() + "_from_" + fBlock.getLabel().getLocalName()).replace('@', 'b').replace(':', '_'));
|
||||||
}
|
}
|
||||||
@ -914,11 +914,11 @@ public class Pass4CodeGeneration {
|
|||||||
RValue rValue = assignment.getrValue();
|
RValue rValue = assignment.getrValue();
|
||||||
Statement statement = assignment.getPhiBlock();
|
Statement statement = assignment.getPhiBlock();
|
||||||
// Generate an ASM move fragment
|
// Generate an ASM move fragment
|
||||||
asm.startSegment(scope, statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
|
asm.startChunk(scope, statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
|
||||||
asm.getCurrentSegment().setPhiTransitionId(transition.getTransitionId());
|
asm.getCurrentChunk().setPhiTransitionId(transition.getTransitionId());
|
||||||
asm.getCurrentSegment().setPhiTransitionAssignmentIdx(assignment.getAssignmentIdx());
|
asm.getCurrentChunk().setPhiTransitionAssignmentIdx(assignment.getAssignmentIdx());
|
||||||
if(isRegisterCopy(lValue, rValue)) {
|
if(isRegisterCopy(lValue, rValue)) {
|
||||||
asm.getCurrentSegment().setFragment("register_copy");
|
asm.getCurrentChunk().setFragment("register_copy");
|
||||||
} else {
|
} else {
|
||||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(lValue, rValue, program, scope);
|
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(lValue, rValue, program, scope);
|
||||||
generateAsm(asm, asmFragmentInstanceSpecFactory);
|
generateAsm(asm, asmFragmentInstanceSpecFactory);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.asm.AsmChunk;
|
||||||
import dk.camelot64.kickc.asm.AsmClobber;
|
import dk.camelot64.kickc.asm.AsmClobber;
|
||||||
import dk.camelot64.kickc.asm.AsmLine;
|
import dk.camelot64.kickc.asm.AsmLine;
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.asm.AsmSegment;
|
|
||||||
import dk.camelot64.kickc.model.CallGraph;
|
import dk.camelot64.kickc.model.CallGraph;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||||
@ -35,17 +35,17 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
|||||||
getLog().append("Interrupt procedure "+procedure.getFullName()+" clobbers "+procClobber.toString());
|
getLog().append("Interrupt procedure "+procedure.getFullName()+" clobbers "+procClobber.toString());
|
||||||
|
|
||||||
// Find the entry/exit blocks for the interrupt
|
// Find the entry/exit blocks for the interrupt
|
||||||
AsmSegment interruptEntry = null;
|
AsmChunk interruptEntry = null;
|
||||||
AsmSegment interruptExit = null;
|
AsmChunk interruptExit = null;
|
||||||
for(AsmSegment asmSegment : getProgram().getAsm().getSegments()) {
|
for(AsmChunk asmChunk : getProgram().getAsm().getChunks()) {
|
||||||
if(procedure.getFullName().equals(asmSegment.getScopeLabel())) {
|
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
|
||||||
if(asmSegment.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
||||||
if(asmSegment.getSource().contains("entry interrupt")) {
|
if(asmChunk.getSource().contains("entry interrupt")) {
|
||||||
interruptEntry = asmSegment;
|
interruptEntry = asmChunk;
|
||||||
} else if(asmSegment.getSource().contains("exit interrupt")) {
|
} else if(asmChunk.getSource().contains("exit interrupt")) {
|
||||||
interruptExit = asmSegment;
|
interruptExit = asmChunk;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Unknown interrupt ASM segment "+asmSegment.getSource());
|
throw new RuntimeException("Unknown interrupt ASM chunk "+ asmChunk.getSource());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -71,14 +71,14 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
|||||||
private AsmClobber getProcedureClobber(Procedure procedure) {
|
private AsmClobber getProcedureClobber(Procedure procedure) {
|
||||||
AsmProgram asm = getProgram().getAsm();
|
AsmProgram asm = getProgram().getAsm();
|
||||||
AsmClobber procClobber =new AsmClobber();
|
AsmClobber procClobber =new AsmClobber();
|
||||||
for(AsmSegment asmSegment : asm.getSegments()) {
|
for(AsmChunk asmChunk : asm.getChunks()) {
|
||||||
if(procedure.getFullName().equals(asmSegment.getScopeLabel())) {
|
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
|
||||||
if(asmSegment.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
||||||
// Do not count clobber in the entry/exit
|
// Do not count clobber in the entry/exit
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AsmClobber asmSegmentClobber = asmSegment.getClobber();
|
AsmClobber asmChunkClobber = asmChunk.getClobber();
|
||||||
procClobber.add(asmSegmentClobber);
|
procClobber.add(asmChunkClobber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
|||||||
return notClobberedRegisters;
|
return notClobberedRegisters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pruneNonClobberedInterruptLines(AsmSegment interruptEntryExit, List<String> notClobberedRegisters) {
|
private void pruneNonClobberedInterruptLines(AsmChunk interruptEntryExit, List<String> notClobberedRegisters) {
|
||||||
ListIterator<AsmLine> entryLines = interruptEntryExit.getLines().listIterator();
|
ListIterator<AsmLine> entryLines = interruptEntryExit.getLines().listIterator();
|
||||||
while(entryLines.hasNext()) {
|
while(entryLines.hasNext()) {
|
||||||
AsmLine line = entryLines.next();
|
AsmLine line = entryLines.next();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.asm.AsmSegment;
|
import dk.camelot64.kickc.asm.AsmChunk;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentInstance;
|
import dk.camelot64.kickc.fragment.AsmFragmentInstance;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||||
import dk.camelot64.kickc.model.*;
|
import dk.camelot64.kickc.model.*;
|
||||||
@ -158,16 +158,16 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
|||||||
int score = 0;
|
int score = 0;
|
||||||
AsmProgram asm = program.getAsm();
|
AsmProgram asm = program.getAsm();
|
||||||
NaturalLoopSet loopSet = program.getLoopSet();
|
NaturalLoopSet loopSet = program.getLoopSet();
|
||||||
for(AsmSegment asmSegment : asm.getSegments()) {
|
for(AsmChunk asmChunk : asm.getChunks()) {
|
||||||
double asmSegmentCycles = asmSegment.getCycles();
|
double asmChunkCycles = asmChunk.getCycles();
|
||||||
if(asmSegmentCycles > 0) {
|
if(asmChunkCycles > 0) {
|
||||||
Integer statementIdx = asmSegment.getStatementIdx();
|
Integer statementIdx = asmChunk.getStatementIdx();
|
||||||
int maxLoopDepth = 1;
|
int maxLoopDepth = 1;
|
||||||
if(statementIdx != null) {
|
if(statementIdx != null) {
|
||||||
ControlFlowBlock block = program.getStatementInfos().getBlock(statementIdx);
|
ControlFlowBlock block = program.getStatementInfos().getBlock(statementIdx);
|
||||||
maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
|
maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
|
||||||
}
|
}
|
||||||
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
|
score += asmChunkCycles * Math.pow(10, maxLoopDepth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
|
@ -160,7 +160,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
combination.allocate(getProgram());
|
combination.allocate(getProgram());
|
||||||
// Generate ASM
|
// Generate ASM
|
||||||
AsmProgram asm = new AsmProgram();
|
AsmProgram asm = new AsmProgram();
|
||||||
asm.startSegment(block.getScope(), statement.getIndex(), statement.toString(getProgram(), false));
|
asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(getProgram(), false));
|
||||||
Pass4CodeGeneration.AsmCodegenAluState aluState = new Pass4CodeGeneration.AsmCodegenAluState();
|
Pass4CodeGeneration.AsmCodegenAluState aluState = new Pass4CodeGeneration.AsmCodegenAluState();
|
||||||
try {
|
try {
|
||||||
(new Pass4CodeGeneration(getProgram(), false)).generateStatementAsm(asm, block, statement, aluState, false);
|
(new Pass4CodeGeneration(getProgram(), false)).generateStatementAsm(asm, block, statement, aluState, false);
|
||||||
|
@ -17,10 +17,10 @@ public class Pass5AddMainRts extends Pass5AsmOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean optimize() {
|
public boolean optimize() {
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
String scopeLabel = segment.getScopeLabel();
|
String scopeLabel = chunk.getScopeLabel();
|
||||||
if(scopeLabel.equals(ScopeRef.ROOT.getFullName())) {
|
if(scopeLabel.equals(ScopeRef.ROOT.getFullName())) {
|
||||||
ListIterator<AsmLine> lineIterator = segment.getLines().listIterator();
|
ListIterator<AsmLine> lineIterator = chunk.getLines().listIterator();
|
||||||
while(lineIterator.hasNext()) {
|
while(lineIterator.hasNext()) {
|
||||||
AsmLine line = lineIterator.next();
|
AsmLine line = lineIterator.next();
|
||||||
if(line instanceof AsmInstruction) {
|
if(line instanceof AsmInstruction) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.CompileLog;
|
import dk.camelot64.kickc.CompileLog;
|
||||||
|
import dk.camelot64.kickc.asm.AsmChunk;
|
||||||
import dk.camelot64.kickc.asm.AsmLine;
|
import dk.camelot64.kickc.asm.AsmLine;
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.asm.AsmSegment;
|
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -43,9 +43,9 @@ public abstract class Pass5AsmOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void remove(List<AsmLine> remove) {
|
public void remove(List<AsmLine> remove) {
|
||||||
Collection<AsmSegment> segments = getAsmProgram().getSegments();
|
Collection<AsmChunk> chunks = getAsmProgram().getChunks();
|
||||||
for(AsmSegment segment : segments) {
|
for(AsmChunk chunk : chunks) {
|
||||||
for(Iterator<AsmLine> iterator = segment.getLines().iterator(); iterator.hasNext(); ) {
|
for(Iterator<AsmLine> iterator = chunk.getLines().iterator(); iterator.hasNext(); ) {
|
||||||
AsmLine line = iterator.next();
|
AsmLine line = iterator.next();
|
||||||
if(remove.contains(line)) {
|
if(remove.contains(line)) {
|
||||||
getLog().append("Removing instruction " + line.getAsm());
|
getLog().append("Removing instruction " + line.getAsm());
|
||||||
|
@ -22,8 +22,8 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization {
|
|||||||
String currentScope = "";
|
String currentScope = "";
|
||||||
String currentLabel = null;
|
String currentLabel = null;
|
||||||
Map<String, String> immediateJumps = new LinkedHashMap<>();
|
Map<String, String> immediateJumps = new LinkedHashMap<>();
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
if(line instanceof AsmScopeBegin) {
|
if(line instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) line).getLabel();
|
currentScope = ((AsmScopeBegin) line).getLabel();
|
||||||
currentLabel = null;
|
currentLabel = null;
|
||||||
@ -56,8 +56,8 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look through the code for double-jumps
|
// Look through the code for double-jumps
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
if(line instanceof AsmScopeBegin) {
|
if(line instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) line).getLabel();
|
currentScope = ((AsmScopeBegin) line).getLabel();
|
||||||
} else if(line instanceof AsmScopeEnd) {
|
} else if(line instanceof AsmScopeEnd) {
|
||||||
|
@ -131,10 +131,10 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
|
|||||||
*/
|
*/
|
||||||
private boolean fixLongBranch(int idx) {
|
private boolean fixLongBranch(int idx) {
|
||||||
AsmProgram asm = getProgram().getAsm();
|
AsmProgram asm = getProgram().getAsm();
|
||||||
AsmSegment asmSegment = asm.getAsmSegment(idx);
|
AsmChunk asmChunk = asm.getAsmChunk(idx);
|
||||||
if(asmSegment != null) {
|
if(asmChunk != null) {
|
||||||
//getLog().append("Found ASM segment "+asmSegment);
|
//getLog().append("Found ASM chunk "+asmChunk);
|
||||||
AsmLine asmLine = asmSegment.getAsmLine(idx);
|
AsmLine asmLine = asmChunk.getAsmLine(idx);
|
||||||
if(asmLine != null && asmLine instanceof AsmInstruction) {
|
if(asmLine != null && asmLine instanceof AsmInstruction) {
|
||||||
//getLog().append("Found ASM line "+asmLine);
|
//getLog().append("Found ASM line "+asmLine);
|
||||||
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
|
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
|
||||||
@ -149,8 +149,8 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
|
|||||||
asmInstruction.setParameter(newLabel+"+");
|
asmInstruction.setParameter(newLabel+"+");
|
||||||
AsmInstructionType jmpType = AsmInstructionSet.getInstructionType("jmp", AsmAddressingMode.ABS, false);
|
AsmInstructionType jmpType = AsmInstructionSet.getInstructionType("jmp", AsmAddressingMode.ABS, false);
|
||||||
AsmInstruction jmpInstruction = new AsmInstruction(jmpType, branchDest);
|
AsmInstruction jmpInstruction = new AsmInstruction(jmpType, branchDest);
|
||||||
asmSegment.addLineAfter(asmInstruction, jmpInstruction);
|
asmChunk.addLineAfter(asmInstruction, jmpInstruction);
|
||||||
asmSegment.addLineAfter(jmpInstruction, new AsmLabel(newLabel));
|
asmChunk.addLineAfter(jmpInstruction, new AsmLabel(newLabel));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ public class Pass5NextJumpElimination extends Pass5AsmOptimization {
|
|||||||
public boolean optimize() {
|
public boolean optimize() {
|
||||||
List<AsmLine> removeLines = new ArrayList<>();
|
List<AsmLine> removeLines = new ArrayList<>();
|
||||||
AsmInstruction candidate = null;
|
AsmInstruction candidate = null;
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
if(line instanceof AsmScopeBegin || line instanceof AsmScopeEnd) {
|
if(line instanceof AsmScopeBegin || line instanceof AsmScopeEnd) {
|
||||||
candidate = null;
|
candidate = null;
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ public class Pass5RedundantLabelElimination extends Pass5AsmOptimization {
|
|||||||
|
|
||||||
List<AsmLine> removeLines = new ArrayList<>();
|
List<AsmLine> removeLines = new ArrayList<>();
|
||||||
String currentScope = "";
|
String currentScope = "";
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
if(line instanceof AsmScopeBegin) {
|
if(line instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) line).getLabel();
|
currentScope = ((AsmScopeBegin) line).getLabel();
|
||||||
} else if(line instanceof AsmScopeEnd) {
|
} else if(line instanceof AsmScopeEnd) {
|
||||||
@ -95,8 +95,8 @@ public class Pass5RedundantLabelElimination extends Pass5AsmOptimization {
|
|||||||
List<RedundantLabels> redundantLabelSet = new ArrayList<>();
|
List<RedundantLabels> redundantLabelSet = new ArrayList<>();
|
||||||
RedundantLabels current = null;
|
RedundantLabels current = null;
|
||||||
String currentScope = "";
|
String currentScope = "";
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
boolean handled = false;
|
boolean handled = false;
|
||||||
if(line instanceof AsmScopeBegin) {
|
if(line instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) line).getLabel();
|
currentScope = ((AsmScopeBegin) line).getLabel();
|
||||||
|
@ -14,8 +14,8 @@ public class Pass5ReindexAsmLines extends Pass5AsmOptimization {
|
|||||||
|
|
||||||
public boolean optimize() {
|
public boolean optimize() {
|
||||||
int nextIndex =0;
|
int nextIndex =0;
|
||||||
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
|
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine asmLine : asmSegment.getLines()) {
|
for(AsmLine asmLine : asmChunk.getLines()) {
|
||||||
if((asmLine instanceof AsmComment)) {
|
if((asmLine instanceof AsmComment)) {
|
||||||
asmLine.setIndex(nextIndex);
|
asmLine.setIndex(nextIndex);
|
||||||
nextIndex += ((AsmComment) asmLine).getLineCount();
|
nextIndex += ((AsmComment) asmLine).getLineCount();
|
||||||
|
@ -24,8 +24,8 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization {
|
|||||||
// Scope->Set<Labels>
|
// Scope->Set<Labels>
|
||||||
Map<String, Set<String>> allLabels = new LinkedHashMap<>();
|
Map<String, Set<String>> allLabels = new LinkedHashMap<>();
|
||||||
String currentScope = "";
|
String currentScope = "";
|
||||||
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
|
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine asmLine : asmSegment.getLines()) {
|
for(AsmLine asmLine : asmChunk.getLines()) {
|
||||||
if(asmLine instanceof AsmScopeBegin) {
|
if(asmLine instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) asmLine).getLabel();
|
currentScope = ((AsmScopeBegin) asmLine).getLabel();
|
||||||
} else if(asmLine instanceof AsmScopeEnd) {
|
} else if(asmLine instanceof AsmScopeEnd) {
|
||||||
@ -47,8 +47,8 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization {
|
|||||||
// Find relabels for all long labels
|
// Find relabels for all long labels
|
||||||
// Scope->(Label->NewLabel)
|
// Scope->(Label->NewLabel)
|
||||||
Map<String, Map<String, String>> relabels = new LinkedHashMap<>();
|
Map<String, Map<String, String>> relabels = new LinkedHashMap<>();
|
||||||
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
|
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine asmLine : asmSegment.getLines()) {
|
for(AsmLine asmLine : asmChunk.getLines()) {
|
||||||
if(asmLine instanceof AsmScopeBegin) {
|
if(asmLine instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) asmLine).getLabel();
|
currentScope = ((AsmScopeBegin) asmLine).getLabel();
|
||||||
} else if(asmLine instanceof AsmScopeEnd) {
|
} else if(asmLine instanceof AsmScopeEnd) {
|
||||||
@ -78,8 +78,8 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute relabelling
|
// Execute relabelling
|
||||||
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
|
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine asmLine : asmSegment.getLines()) {
|
for(AsmLine asmLine : asmChunk.getLines()) {
|
||||||
if(asmLine instanceof AsmScopeBegin) {
|
if(asmLine instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) asmLine).getLabel();
|
currentScope = ((AsmScopeBegin) asmLine).getLabel();
|
||||||
} else if(asmLine instanceof AsmScopeEnd) {
|
} else if(asmLine instanceof AsmScopeEnd) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.asm.AsmBasicUpstart;
|
import dk.camelot64.kickc.asm.AsmBasicUpstart;
|
||||||
|
import dk.camelot64.kickc.asm.AsmChunk;
|
||||||
import dk.camelot64.kickc.asm.AsmInstruction;
|
import dk.camelot64.kickc.asm.AsmInstruction;
|
||||||
import dk.camelot64.kickc.asm.AsmLine;
|
import dk.camelot64.kickc.asm.AsmLine;
|
||||||
import dk.camelot64.kickc.asm.AsmSegment;
|
|
||||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.statements.Statement;
|
import dk.camelot64.kickc.model.statements.Statement;
|
||||||
@ -31,8 +31,8 @@ public class Pass5SkipBegin extends Pass5AsmOptimization {
|
|||||||
boolean optimized = false;
|
boolean optimized = false;
|
||||||
if(canSkip) {
|
if(canSkip) {
|
||||||
// Change BasicUpstart() to call main directly and remove the JSR main
|
// Change BasicUpstart() to call main directly and remove the JSR main
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
ListIterator<AsmLine> lineIterator = segment.getLines().listIterator();
|
ListIterator<AsmLine> lineIterator = chunk.getLines().listIterator();
|
||||||
while(lineIterator.hasNext()) {
|
while(lineIterator.hasNext()) {
|
||||||
AsmLine line = lineIterator.next();
|
AsmLine line = lineIterator.next();
|
||||||
if(line instanceof AsmBasicUpstart) {
|
if(line instanceof AsmBasicUpstart) {
|
||||||
|
@ -20,8 +20,8 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
|||||||
AsmProgramStaticRegisterValues staticValues = new AsmProgramStaticRegisterValues(getAsmProgram());
|
AsmProgramStaticRegisterValues staticValues = new AsmProgramStaticRegisterValues(getAsmProgram());
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
|
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
List<AsmLine> lines = segment.getLines();
|
List<AsmLine> lines = chunk.getLines();
|
||||||
ListIterator<AsmLine> lineIt = lines.listIterator();
|
ListIterator<AsmLine> lineIt = lines.listIterator();
|
||||||
while(lineIt.hasNext()) {
|
while(lineIt.hasNext()) {
|
||||||
AsmLine line = lineIt.next();
|
AsmLine line = lineIt.next();
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.asm.AsmChunk;
|
||||||
import dk.camelot64.kickc.asm.AsmComment;
|
import dk.camelot64.kickc.asm.AsmComment;
|
||||||
import dk.camelot64.kickc.asm.AsmInstruction;
|
import dk.camelot64.kickc.asm.AsmInstruction;
|
||||||
import dk.camelot64.kickc.asm.AsmLine;
|
import dk.camelot64.kickc.asm.AsmLine;
|
||||||
import dk.camelot64.kickc.asm.AsmSegment;
|
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
|
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
@ -23,8 +23,8 @@ public class Pass5UnreachableCodeElimination extends Pass5AsmOptimization {
|
|||||||
|
|
||||||
// Find RTS/JMP followed by code
|
// Find RTS/JMP followed by code
|
||||||
boolean afterExit = false;
|
boolean afterExit = false;
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
ListIterator<AsmLine> lineIt = segment.getLines().listIterator();
|
ListIterator<AsmLine> lineIt = chunk.getLines().listIterator();
|
||||||
while(lineIt.hasNext()) {
|
while(lineIt.hasNext()) {
|
||||||
AsmLine line = lineIt.next();
|
AsmLine line = lineIt.next();
|
||||||
if(line instanceof AsmInstruction) {
|
if(line instanceof AsmInstruction) {
|
||||||
|
@ -30,8 +30,8 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization {
|
|||||||
private Set<String> findUsedLabels() {
|
private Set<String> findUsedLabels() {
|
||||||
Set<String> usedLabels = new LinkedHashSet<>();
|
Set<String> usedLabels = new LinkedHashSet<>();
|
||||||
String currentScope = "";
|
String currentScope = "";
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
if(line instanceof AsmScopeBegin) {
|
if(line instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) line).getLabel();
|
currentScope = ((AsmScopeBegin) line).getLabel();
|
||||||
} else if(line instanceof AsmScopeEnd) {
|
} else if(line instanceof AsmScopeEnd) {
|
||||||
@ -55,8 +55,8 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization {
|
|||||||
private List<AsmLine> findUnusedLabelLines(Set<String> usedLabels) {
|
private List<AsmLine> findUnusedLabelLines(Set<String> usedLabels) {
|
||||||
List<AsmLine> removeLines = new ArrayList<>();
|
List<AsmLine> removeLines = new ArrayList<>();
|
||||||
String currentScope = "";
|
String currentScope = "";
|
||||||
for(AsmSegment segment : getAsmProgram().getSegments()) {
|
for(AsmChunk chunk : getAsmProgram().getChunks()) {
|
||||||
Integer statementIdx = segment.getStatementIdx();
|
Integer statementIdx = chunk.getStatementIdx();
|
||||||
if(statementIdx != null) {
|
if(statementIdx != null) {
|
||||||
Statement statement = getProgram().getStatementInfos().getStatement(statementIdx);
|
Statement statement = getProgram().getStatementInfos().getStatement(statementIdx);
|
||||||
if(statement instanceof StatementAsm) {
|
if(statement instanceof StatementAsm) {
|
||||||
@ -64,7 +64,7 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(AsmLine line : segment.getLines()) {
|
for(AsmLine line : chunk.getLines()) {
|
||||||
if(line instanceof AsmScopeBegin) {
|
if(line instanceof AsmScopeBegin) {
|
||||||
currentScope = ((AsmScopeBegin) line).getLabel();
|
currentScope = ((AsmScopeBegin) line).getLabel();
|
||||||
} else if(line instanceof AsmScopeEnd) {
|
} else if(line instanceof AsmScopeEnd) {
|
||||||
|
Loading…
Reference in New Issue
Block a user