1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-23 23:32:55 +00:00

Renamed AsmSegment to AsmChunk in preparation for introduction of KickAsm segments. #113

This commit is contained in:
jespergravgaard 2019-08-08 23:37:43 +02:00
parent 31a3bd9078
commit fe93a48360
21 changed files with 172 additions and 173 deletions

View File

@ -12,49 +12,49 @@ import java.util.ListIterator;
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.
* Typically each ICL statement becomes a single ASM segment through the AsmFragment subsystem.
* 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 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;
/**
* Index of the segment.
* Index of the chunk.
*/
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;
/**
* Readable name of the ICL source of the segment.
* Readable name of the ICL source of the chunk.
*/
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;
/** 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;
/** 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;
/** The full name of the containing scope (procedure). */
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;
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.scopeLabel = scope.getFullName();
this.index = index;
@ -133,8 +133,8 @@ public class AsmSegment {
}
/**
* Get the number of bytes the segment occupies in memory.
* Per default calculated by adding up the bytes of each ASM line in the segment.
* Get the number of bytes the chunk occupies in memory.
* Per default calculated by adding up the bytes of each ASM line in the chunk.
*
* @return The number of bytes
*/
@ -147,8 +147,8 @@ public class AsmSegment {
}
/**
* Get the number of cycles it takes to execute the segment
* Per default calculated by adding up the cycles of each ASM line in 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 chunk.
*
* @return The number of cycles
*/
@ -161,8 +161,8 @@ public class AsmSegment {
}
/**
* Get the registers clobbered when executing the segment
* Per default calculated by adding up the clobber of each ASM line in the segment.
* Get the registers clobbered when executing the chunk
* Per default calculated by adding up the clobber of each ASM line in the chunk.
*
* @return The registers clobbered
*/
@ -186,7 +186,7 @@ public class AsmSegment {
* Get ASM line by index
*
* @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) {
for(AsmLine asmLine : getLines()) {
@ -246,7 +246,7 @@ public class AsmSegment {
}
if(printState.isSourceIclInfo()) {
out.append(printState.getIndent()).append(" //");
if(printState.isSourceSegmentIdInfo()) {
if(printState.isSourceChunkIdInfo()) {
out.append("SEG").append(getIndex());
}
if(source != null) {

View File

@ -14,14 +14,14 @@ import java.util.List;
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.
@ -29,28 +29,28 @@ public class AsmProgram {
private int nextLineIndex;
public AsmProgram() {
this.segments = new ArrayList<>();
this.chunks = new ArrayList<>();
this.nextLineIndex = 0;
this.nextSegmentIndex = 0;
this.nextChunkIndex = 0;
}
public Collection<AsmSegment> getSegments() {
return segments;
public Collection<AsmChunk> getChunks() {
return chunks;
}
public AsmSegment startSegment(ScopeRef scopeRef, Integer statementIndex, String source) {
AsmSegment segment = new AsmSegment(nextSegmentIndex++, scopeRef, statementIndex, source);
segments.add(segment);
return segment;
public AsmChunk startChunk(ScopeRef scopeRef, Integer statementIndex, String source) {
AsmChunk chunk = new AsmChunk(nextChunkIndex++, scopeRef, statementIndex, source);
chunks.add(chunk);
return chunk;
}
public AsmSegment getCurrentSegment() {
return segments.get(segments.size() - 1);
public AsmChunk getCurrentChunk() {
return chunks.get(chunks.size() - 1);
}
public void addLine(AsmLine line) {
line.setIndex(nextLineIndex++);
getCurrentSegment().addLine(line);
getCurrentChunk().addLine(line);
}
public void addComment(String comment, boolean isBlock) {
@ -236,51 +236,51 @@ public class AsmProgram {
}
/**
* Get the number of bytes the segment occupies in memory.
* Calculated by adding up the bytes of each ASM segment in the program.
* Get the number of bytes the program occupies in memory.
* Calculated by adding up the bytes of each ASM chunk in the program.
*
* @return The number of bytes
*/
public int getBytes() {
int bytes = 0;
for(AsmSegment segment : segments) {
bytes += segment.getBytes();
for(AsmChunk chunk : chunks) {
bytes += chunk.getBytes();
}
return bytes;
}
/**
* Get the number of cycles it takes to execute the segment
* Calculated by adding up the cycles of each ASM segments in the program.
* Get the number of cycles it takes to execute the program
* Calculated by adding up the cycles of each ASM chunks in the program.
*
* @return The number of cycles
*/
public double getCycles() {
double cycles = 0.0;
for(AsmSegment segment : segments) {
cycles += segment.getCycles();
for(AsmChunk chunk : chunks) {
cycles += chunk.getCycles();
}
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
*/
public AsmClobber getClobber() {
AsmClobber clobber = new AsmClobber();
for(AsmSegment segment : segments) {
clobber.add(segment.getClobber());
for(AsmChunk chunk : chunks) {
clobber.add(chunk.getClobber());
}
return clobber;
}
public String toString(AsmPrintState printState, Program program) {
StringBuilder out = new StringBuilder();
for(AsmSegment segment : segments) {
out.append(segment.toString(printState, program));
for(AsmChunk chunk : chunks) {
out.append(chunk.toString(printState, program));
}
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
* @return The segment with the line that has the passed index. Null if not found
* @param idx The index of the line to get the chunk for
* @return The chunk with the line that has the passed index. Null if not found
*/
public AsmSegment getAsmSegment(int idx) {
for(AsmSegment segment : segments) {
for(AsmLine asmLine : segment.getLines()) {
public AsmChunk getAsmChunk(int idx) {
for(AsmChunk chunk : chunks) {
for(AsmLine asmLine : chunk.getLines()) {
if(asmLine.getIndex() == idx) {
return segment;
return chunk;
}
}
}
@ -323,8 +323,8 @@ public class AsmProgram {
private boolean sourceCodeInfo;
// Output comments with ICL-code and the ASM fragment name
private boolean sourceIclInfo;
// Output segment ID in the ICL-comment
private boolean sourceSegmentIdInfo;
// Output chunk ID in the ICL-comment
private boolean sourceChunkIdInfo;
// Output ASM line numbers
private boolean asmLineNumber;
// Current indent - used during printing
@ -366,12 +366,12 @@ public class AsmProgram {
return sourceIclInfo;
}
public boolean isSourceSegmentIdInfo() {
return sourceSegmentIdInfo;
public boolean isSourceChunkIdInfo() {
return sourceChunkIdInfo;
}
public void setSourceSegmentIdInfo(boolean sourceSegmentIdInfo) {
this.sourceSegmentIdInfo = sourceSegmentIdInfo;
public void setSourceChunkIdInfo(boolean sourceChunkIdInfo) {
this.sourceChunkIdInfo = sourceChunkIdInfo;
}
public void setSourceIclInfo(boolean sourceIclInfo) {

View File

@ -65,8 +65,8 @@ public class AsmProgramStaticRegisterValues {
private void initValues() {
AsmRegisterValues current = new AsmRegisterValues();
for(AsmSegment segment : program.getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : program.getChunks()) {
for(AsmLine line : chunk.getLines()) {
current = updateStaticRegisterValues(current, line);
}
}

View File

@ -114,7 +114,7 @@ public class AsmFragmentTemplate {
AsmFragmentInstance fragmentInstance =
new AsmFragmentInstance(new Program(), signature, ScopeRef.ROOT, this, bindings);
AsmProgram asm = new AsmProgram();
asm.startSegment(ScopeRef.ROOT, null, signature);
asm.startChunk(ScopeRef.ROOT, null, signature);
fragmentInstance.generate(asm);
AsmClobber asmClobber = asm.getClobber();
this.clobber = new AsmFragmentClobber(asmClobber);

View File

@ -2,9 +2,8 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmClobber;
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.statements.StatementSource;
import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.VariableRef;
@ -61,23 +60,23 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
AsmProgram asm = getProgram().getAsm();
boolean clobberProblem = false;
for(AsmSegment asmSegment : asm.getSegments()) {
if(asmSegment.getStatementIdx() != null) {
for(AsmChunk asmChunk : asm.getChunks()) {
if(asmChunk.getStatementIdx() != null) {
// Find the ICL statement
int statementIdx = asmSegment.getStatementIdx();
int statementIdx = asmChunk.getStatementIdx();
Statement statement = getProgram().getStatementInfos().getStatement(statementIdx);
// Find the registered clobbered by the ASM asmSegment
AsmClobber asmSegmentClobber = asmSegment.getClobber();
Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
// Find the registered clobbered by the ASM asmChunk
AsmClobber asmChunkClobber = asmChunk.getClobber();
Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmChunkClobber);
// Find vars assigned to in the statement
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
// Find alive variables
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(asmSegment.getPhiTransitionId() != null && asmSegment.getPhiTransitionAssignmentIdx() != null) {
String phiTransitionId = asmSegment.getPhiTransitionId();
int transitionAssignmentIdx = asmSegment.getPhiTransitionAssignmentIdx();
// 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(asmChunk.getPhiTransitionId() != null && asmChunk.getPhiTransitionAssignmentIdx() != null) {
String phiTransitionId = asmChunk.getPhiTransitionId();
int transitionAssignmentIdx = asmChunk.getPhiTransitionAssignmentIdx();
ControlFlowBlock statementBlock = getProgram().getStatementInfos().getBlock(statementIdx);
Map<LabelRef, PhiTransitions> programPhiTransitions = getProgram().getPhiTransitions();
PhiTransitions phiTransitions = programPhiTransitions.get(statementBlock.getLabel());

View File

@ -74,7 +74,7 @@ public class Pass4CodeGeneration {
ScopeRef currentScope = ScopeRef.ROOT;
// Add file level comments
asm.startSegment(currentScope, null, "File Comments");
asm.startChunk(currentScope, null, "File Comments");
generateComments(asm, program.getFileComments());
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())) {
asm.addLine(new AsmSetPc("Basic", AsmFormat.getAsmNumber(0x0801)));
asm.addLine(new AsmBasicUpstart("bbegin"));
@ -96,7 +96,7 @@ public class Pass4CodeGeneration {
asm.addLine(new AsmSetPc("Program", AsmFormat.getAsmNumber(programPc)));
// Generate global ZP labels
asm.startSegment(currentScope, null, "Global Constants & labels");
asm.startChunk(currentScope, null, "Global Constants & labels");
addConstants(asm, currentScope);
addZpLabels(asm, currentScope);
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
@ -104,7 +104,7 @@ public class Pass4CodeGeneration {
// The current block is in a different scope. End the old scope.
generateScopeEnding(asm, currentScope);
currentScope = block.getScope();
asm.startSegment(currentScope, null, block.getLabel().getFullName());
asm.startChunk(currentScope, null, block.getLabel().getFullName());
// Add any procedure comments
if(block.isProcedureEntry(program)) {
Procedure procedure = block.getProcedure(program);
@ -132,7 +132,7 @@ public class Pass4CodeGeneration {
}
} else {
// 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(':', '_'));
}
// Generate statements
@ -159,7 +159,7 @@ public class Pass4CodeGeneration {
generateScopeEnding(asm, currentScope);
currentScope = ScopeRef.ROOT;
asm.startSegment(currentScope, null, "File Data");
asm.startChunk(currentScope, null, "File Data");
addData(asm, ScopeRef.ROOT);
// Add all absolutely placed inline KickAsm
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
@ -168,11 +168,11 @@ public class Pass4CodeGeneration {
StatementKickAsm statementKasm = (StatementKickAsm) statement;
if(statementKasm.getLocation() != null) {
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_]*")) {
segmentName = asmLocation;
chunkName = asmLocation;
}
asm.addLine(new AsmSetPc(segmentName, asmLocation));
asm.addLine(new AsmSetPc(chunkName, asmLocation));
addKickAsm(asm, statementKasm);
}
}
@ -606,7 +606,7 @@ public class Pass4CodeGeneration {
public void generateStatementAsm(AsmProgram asm, ControlFlowBlock block, Statement statement, AsmCodegenAluState
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());
// IF the previous statement was added to the ALU register - generate the composite ASM fragment
if(aluState.hasAluAssignment()) {
@ -680,16 +680,16 @@ public class Pass4CodeGeneration {
HashMap<String, Value> bindings = new HashMap<>();
AsmFragmentInstance asmFragmentInstance = new AsmFragmentInstance(program, "inline", block.getScope(), new AsmFragmentTemplate(statementAsm.getAsmLines()), bindings);
asmFragmentInstance.generate(asm);
AsmSegment currentSegment = asm.getCurrentSegment();
AsmChunk currentChunk = asm.getCurrentChunk();
if(statementAsm.getDeclaredClobber() != null) {
currentSegment.setClobberOverwrite(statementAsm.getDeclaredClobber());
currentChunk.setClobberOverwrite(statementAsm.getDeclaredClobber());
} else {
for(AsmLine asmLine : currentSegment.getLines()) {
for(AsmLine asmLine : currentChunk.getLines()) {
if(asmLine instanceof AsmInstruction) {
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
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);
}
if(statementKasm.getDeclaredClobber() != null) {
asm.getCurrentSegment().setClobberOverwrite(statementKasm.getDeclaredClobber());
asm.getCurrentChunk().setClobberOverwrite(statementKasm.getDeclaredClobber());
}
} else if(statement instanceof StatementCallPointer) {
StatementCallPointer callPointer = (StatementCallPointer) statement;
@ -738,7 +738,7 @@ public class Pass4CodeGeneration {
}
}
if(supported) {
asm.getCurrentSegment().setClobberOverwrite(AsmClobber.CLOBBER_ALL);
asm.getCurrentChunk().setClobberOverwrite(AsmClobber.CLOBBER_ALL);
}
if(!supported) {
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);
}
@ -790,8 +790,8 @@ public class Pass4CodeGeneration {
*/
private void generateInterruptEntry(AsmProgram asm, Procedure procedure) {
Procedure.InterruptType interruptType = procedure.getInterruptType();
asm.startSegment(procedure.getRef(), null, "entry interrupt(" + interruptType.name() + ")");
//asm.getCurrentSegment().setXXX();
asm.startChunk(procedure.getRef(), null, "entry interrupt(" + interruptType.name() + ")");
//asm.getCurrentChunk().setXXX();
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
// No entry ASM needed
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
@ -819,7 +819,7 @@ public class Pass4CodeGeneration {
* @param interruptType The type of interrupt to generate
*/
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)) {
asm.addInstruction("jmp", AsmAddressingMode.ABS, "$ea81", false);
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
@ -898,13 +898,13 @@ public class Pass4CodeGeneration {
PhiTransitions.PhiTransition transition = transitions.getTransition(fromBlock);
if(!transitionIsGenerated(transition)) {
Statement toFirstStatement = toBlock.getStatements().get(0);
String segmentSrc = "[" + toFirstStatement.getIndex() + "] phi from ";
String chunkSrc = "[" + toFirstStatement.getIndex() + "] phi from ";
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
segmentSrc += fBlock.getLabel().getFullName() + " ";
chunkSrc += fBlock.getLabel().getFullName() + " ";
}
segmentSrc += "to " + toBlock.getLabel().getFullName();
asm.startSegment(scope, toFirstStatement.getIndex(), segmentSrc);
asm.getCurrentSegment().setPhiTransitionId(transition.getTransitionId());
chunkSrc += "to " + toBlock.getLabel().getFullName();
asm.startChunk(scope, toFirstStatement.getIndex(), chunkSrc);
asm.getCurrentChunk().setPhiTransitionId(transition.getTransitionId());
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
asm.addLabel((toBlock.getLabel().getLocalName() + "_from_" + fBlock.getLabel().getLocalName()).replace('@', 'b').replace(':', '_'));
}
@ -914,11 +914,11 @@ public class Pass4CodeGeneration {
RValue rValue = assignment.getrValue();
Statement statement = assignment.getPhiBlock();
// Generate an ASM move fragment
asm.startSegment(scope, statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
asm.getCurrentSegment().setPhiTransitionId(transition.getTransitionId());
asm.getCurrentSegment().setPhiTransitionAssignmentIdx(assignment.getAssignmentIdx());
asm.startChunk(scope, statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
asm.getCurrentChunk().setPhiTransitionId(transition.getTransitionId());
asm.getCurrentChunk().setPhiTransitionAssignmentIdx(assignment.getAssignmentIdx());
if(isRegisterCopy(lValue, rValue)) {
asm.getCurrentSegment().setFragment("register_copy");
asm.getCurrentChunk().setFragment("register_copy");
} else {
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(lValue, rValue, program, scope);
generateAsm(asm, asmFragmentInstanceSpecFactory);

View File

@ -1,9 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmChunk;
import dk.camelot64.kickc.asm.AsmClobber;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.asm.AsmSegment;
import dk.camelot64.kickc.model.CallGraph;
import dk.camelot64.kickc.model.Program;
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());
// Find the entry/exit blocks for the interrupt
AsmSegment interruptEntry = null;
AsmSegment interruptExit = null;
for(AsmSegment asmSegment : getProgram().getAsm().getSegments()) {
if(procedure.getFullName().equals(asmSegment.getScopeLabel())) {
if(asmSegment.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
if(asmSegment.getSource().contains("entry interrupt")) {
interruptEntry = asmSegment;
} else if(asmSegment.getSource().contains("exit interrupt")) {
interruptExit = asmSegment;
AsmChunk interruptEntry = null;
AsmChunk interruptExit = null;
for(AsmChunk asmChunk : getProgram().getAsm().getChunks()) {
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
if(asmChunk.getSource().contains("entry interrupt")) {
interruptEntry = asmChunk;
} else if(asmChunk.getSource().contains("exit interrupt")) {
interruptExit = asmChunk;
} else {
throw new RuntimeException("Unknown interrupt ASM segment "+asmSegment.getSource());
throw new RuntimeException("Unknown interrupt ASM chunk "+ asmChunk.getSource());
}
continue;
}
@ -71,14 +71,14 @@ public class Pass4InterruptClobberFix extends Pass2Base {
private AsmClobber getProcedureClobber(Procedure procedure) {
AsmProgram asm = getProgram().getAsm();
AsmClobber procClobber =new AsmClobber();
for(AsmSegment asmSegment : asm.getSegments()) {
if(procedure.getFullName().equals(asmSegment.getScopeLabel())) {
if(asmSegment.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
for(AsmChunk asmChunk : asm.getChunks()) {
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
// Do not count clobber in the entry/exit
continue;
}
AsmClobber asmSegmentClobber = asmSegment.getClobber();
procClobber.add(asmSegmentClobber);
AsmClobber asmChunkClobber = asmChunk.getClobber();
procClobber.add(asmChunkClobber);
}
}
@ -110,7 +110,7 @@ public class Pass4InterruptClobberFix extends Pass2Base {
return notClobberedRegisters;
}
private void pruneNonClobberedInterruptLines(AsmSegment interruptEntryExit, List<String> notClobberedRegisters) {
private void pruneNonClobberedInterruptLines(AsmChunk interruptEntryExit, List<String> notClobberedRegisters) {
ListIterator<AsmLine> entryLines = interruptEntryExit.getLines().listIterator();
while(entryLines.hasNext()) {
AsmLine line = entryLines.next();

View File

@ -1,7 +1,7 @@
package dk.camelot64.kickc.passes;
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.AsmFragmentTemplateSynthesizer;
import dk.camelot64.kickc.model.*;
@ -158,16 +158,16 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
int score = 0;
AsmProgram asm = program.getAsm();
NaturalLoopSet loopSet = program.getLoopSet();
for(AsmSegment asmSegment : asm.getSegments()) {
double asmSegmentCycles = asmSegment.getCycles();
if(asmSegmentCycles > 0) {
Integer statementIdx = asmSegment.getStatementIdx();
for(AsmChunk asmChunk : asm.getChunks()) {
double asmChunkCycles = asmChunk.getCycles();
if(asmChunkCycles > 0) {
Integer statementIdx = asmChunk.getStatementIdx();
int maxLoopDepth = 1;
if(statementIdx != null) {
ControlFlowBlock block = program.getStatementInfos().getBlock(statementIdx);
maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
}
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
score += asmChunkCycles * Math.pow(10, maxLoopDepth);
}
}
return score;

View File

@ -160,7 +160,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
combination.allocate(getProgram());
// Generate ASM
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();
try {
(new Pass4CodeGeneration(getProgram(), false)).generateStatementAsm(asm, block, statement, aluState, false);

View File

@ -17,10 +17,10 @@ public class Pass5AddMainRts extends Pass5AsmOptimization {
}
public boolean optimize() {
for(AsmSegment segment : getAsmProgram().getSegments()) {
String scopeLabel = segment.getScopeLabel();
for(AsmChunk chunk : getAsmProgram().getChunks()) {
String scopeLabel = chunk.getScopeLabel();
if(scopeLabel.equals(ScopeRef.ROOT.getFullName())) {
ListIterator<AsmLine> lineIterator = segment.getLines().listIterator();
ListIterator<AsmLine> lineIterator = chunk.getLines().listIterator();
while(lineIterator.hasNext()) {
AsmLine line = lineIterator.next();
if(line instanceof AsmInstruction) {

View File

@ -1,9 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmChunk;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.asm.AsmSegment;
import dk.camelot64.kickc.model.Program;
import java.util.Collection;
@ -43,9 +43,9 @@ public abstract class Pass5AsmOptimization {
}
public void remove(List<AsmLine> remove) {
Collection<AsmSegment> segments = getAsmProgram().getSegments();
for(AsmSegment segment : segments) {
for(Iterator<AsmLine> iterator = segment.getLines().iterator(); iterator.hasNext(); ) {
Collection<AsmChunk> chunks = getAsmProgram().getChunks();
for(AsmChunk chunk : chunks) {
for(Iterator<AsmLine> iterator = chunk.getLines().iterator(); iterator.hasNext(); ) {
AsmLine line = iterator.next();
if(remove.contains(line)) {
getLog().append("Removing instruction " + line.getAsm());

View File

@ -22,8 +22,8 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization {
String currentScope = "";
String currentLabel = null;
Map<String, String> immediateJumps = new LinkedHashMap<>();
for(AsmSegment segment : getAsmProgram().getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : getAsmProgram().getChunks()) {
for(AsmLine line : chunk.getLines()) {
if(line instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) line).getLabel();
currentLabel = null;
@ -56,8 +56,8 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization {
}
// Look through the code for double-jumps
for(AsmSegment segment : getAsmProgram().getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : getAsmProgram().getChunks()) {
for(AsmLine line : chunk.getLines()) {
if(line instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) line).getLabel();
} else if(line instanceof AsmScopeEnd) {

View File

@ -131,10 +131,10 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
*/
private boolean fixLongBranch(int idx) {
AsmProgram asm = getProgram().getAsm();
AsmSegment asmSegment = asm.getAsmSegment(idx);
if(asmSegment != null) {
//getLog().append("Found ASM segment "+asmSegment);
AsmLine asmLine = asmSegment.getAsmLine(idx);
AsmChunk asmChunk = asm.getAsmChunk(idx);
if(asmChunk != null) {
//getLog().append("Found ASM chunk "+asmChunk);
AsmLine asmLine = asmChunk.getAsmLine(idx);
if(asmLine != null && asmLine instanceof AsmInstruction) {
//getLog().append("Found ASM line "+asmLine);
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
@ -149,8 +149,8 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
asmInstruction.setParameter(newLabel+"+");
AsmInstructionType jmpType = AsmInstructionSet.getInstructionType("jmp", AsmAddressingMode.ABS, false);
AsmInstruction jmpInstruction = new AsmInstruction(jmpType, branchDest);
asmSegment.addLineAfter(asmInstruction, jmpInstruction);
asmSegment.addLineAfter(jmpInstruction, new AsmLabel(newLabel));
asmChunk.addLineAfter(asmInstruction, jmpInstruction);
asmChunk.addLineAfter(jmpInstruction, new AsmLabel(newLabel));
return true;
}
}

View File

@ -18,8 +18,8 @@ public class Pass5NextJumpElimination extends Pass5AsmOptimization {
public boolean optimize() {
List<AsmLine> removeLines = new ArrayList<>();
AsmInstruction candidate = null;
for(AsmSegment segment : getAsmProgram().getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : getAsmProgram().getChunks()) {
for(AsmLine line : chunk.getLines()) {
if(line instanceof AsmScopeBegin || line instanceof AsmScopeEnd) {
candidate = null;
}

View File

@ -23,8 +23,8 @@ public class Pass5RedundantLabelElimination extends Pass5AsmOptimization {
List<AsmLine> removeLines = new ArrayList<>();
String currentScope = "";
for(AsmSegment segment : getAsmProgram().getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : getAsmProgram().getChunks()) {
for(AsmLine line : chunk.getLines()) {
if(line instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) line).getLabel();
} else if(line instanceof AsmScopeEnd) {
@ -95,8 +95,8 @@ public class Pass5RedundantLabelElimination extends Pass5AsmOptimization {
List<RedundantLabels> redundantLabelSet = new ArrayList<>();
RedundantLabels current = null;
String currentScope = "";
for(AsmSegment segment : getAsmProgram().getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : getAsmProgram().getChunks()) {
for(AsmLine line : chunk.getLines()) {
boolean handled = false;
if(line instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) line).getLabel();

View File

@ -14,8 +14,8 @@ public class Pass5ReindexAsmLines extends Pass5AsmOptimization {
public boolean optimize() {
int nextIndex =0;
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
for(AsmLine asmLine : asmSegment.getLines()) {
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
for(AsmLine asmLine : asmChunk.getLines()) {
if((asmLine instanceof AsmComment)) {
asmLine.setIndex(nextIndex);
nextIndex += ((AsmComment) asmLine).getLineCount();

View File

@ -24,8 +24,8 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization {
// Scope->Set<Labels>
Map<String, Set<String>> allLabels = new LinkedHashMap<>();
String currentScope = "";
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
for(AsmLine asmLine : asmSegment.getLines()) {
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
for(AsmLine asmLine : asmChunk.getLines()) {
if(asmLine instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) asmLine).getLabel();
} else if(asmLine instanceof AsmScopeEnd) {
@ -47,8 +47,8 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization {
// Find relabels for all long labels
// Scope->(Label->NewLabel)
Map<String, Map<String, String>> relabels = new LinkedHashMap<>();
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
for(AsmLine asmLine : asmSegment.getLines()) {
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
for(AsmLine asmLine : asmChunk.getLines()) {
if(asmLine instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) asmLine).getLabel();
} else if(asmLine instanceof AsmScopeEnd) {
@ -78,8 +78,8 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization {
}
// Execute relabelling
for(AsmSegment asmSegment : getAsmProgram().getSegments()) {
for(AsmLine asmLine : asmSegment.getLines()) {
for(AsmChunk asmChunk : getAsmProgram().getChunks()) {
for(AsmLine asmLine : asmChunk.getLines()) {
if(asmLine instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) asmLine).getLabel();
} else if(asmLine instanceof AsmScopeEnd) {

View File

@ -1,9 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmBasicUpstart;
import dk.camelot64.kickc.asm.AsmChunk;
import dk.camelot64.kickc.asm.AsmInstruction;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmSegment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.Statement;
@ -31,8 +31,8 @@ public class Pass5SkipBegin extends Pass5AsmOptimization {
boolean optimized = false;
if(canSkip) {
// Change BasicUpstart() to call main directly and remove the JSR main
for(AsmSegment segment : getAsmProgram().getSegments()) {
ListIterator<AsmLine> lineIterator = segment.getLines().listIterator();
for(AsmChunk chunk : getAsmProgram().getChunks()) {
ListIterator<AsmLine> lineIterator = chunk.getLines().listIterator();
while(lineIterator.hasNext()) {
AsmLine line = lineIterator.next();
if(line instanceof AsmBasicUpstart) {

View File

@ -20,8 +20,8 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
AsmProgramStaticRegisterValues staticValues = new AsmProgramStaticRegisterValues(getAsmProgram());
boolean modified = false;
for(AsmSegment segment : getAsmProgram().getSegments()) {
List<AsmLine> lines = segment.getLines();
for(AsmChunk chunk : getAsmProgram().getChunks()) {
List<AsmLine> lines = chunk.getLines();
ListIterator<AsmLine> lineIt = lines.listIterator();
while(lineIt.hasNext()) {
AsmLine line = lineIt.next();

View File

@ -1,9 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmChunk;
import dk.camelot64.kickc.asm.AsmComment;
import dk.camelot64.kickc.asm.AsmInstruction;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmSegment;
import dk.camelot64.kickc.model.Program;
import java.util.ListIterator;
@ -23,8 +23,8 @@ public class Pass5UnreachableCodeElimination extends Pass5AsmOptimization {
// Find RTS/JMP followed by code
boolean afterExit = false;
for(AsmSegment segment : getAsmProgram().getSegments()) {
ListIterator<AsmLine> lineIt = segment.getLines().listIterator();
for(AsmChunk chunk : getAsmProgram().getChunks()) {
ListIterator<AsmLine> lineIt = chunk.getLines().listIterator();
while(lineIt.hasNext()) {
AsmLine line = lineIt.next();
if(line instanceof AsmInstruction) {

View File

@ -30,8 +30,8 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization {
private Set<String> findUsedLabels() {
Set<String> usedLabels = new LinkedHashSet<>();
String currentScope = "";
for(AsmSegment segment : getAsmProgram().getSegments()) {
for(AsmLine line : segment.getLines()) {
for(AsmChunk chunk : getAsmProgram().getChunks()) {
for(AsmLine line : chunk.getLines()) {
if(line instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) line).getLabel();
} else if(line instanceof AsmScopeEnd) {
@ -55,8 +55,8 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization {
private List<AsmLine> findUnusedLabelLines(Set<String> usedLabels) {
List<AsmLine> removeLines = new ArrayList<>();
String currentScope = "";
for(AsmSegment segment : getAsmProgram().getSegments()) {
Integer statementIdx = segment.getStatementIdx();
for(AsmChunk chunk : getAsmProgram().getChunks()) {
Integer statementIdx = chunk.getStatementIdx();
if(statementIdx != null) {
Statement statement = getProgram().getStatementInfos().getStatement(statementIdx);
if(statement instanceof StatementAsm) {
@ -64,7 +64,7 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization {
continue;
}
}
for(AsmLine line : segment.getLines()) {
for(AsmLine line : chunk.getLines()) {
if(line instanceof AsmScopeBegin) {
currentScope = ((AsmScopeBegin) line).getLabel();
} else if(line instanceof AsmScopeEnd) {