mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 19:50:10 +00:00
Implemented initial KickAsm segment support. #113
This commit is contained in:
parent
9a54c0f814
commit
8f0b9c886f
60
src/main/java/dk/camelot64/kickc/asm/AsmFile.java
Normal file
60
src/main/java/dk/camelot64/kickc/asm/AsmFile.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package dk.camelot64.kickc.asm;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Define a KickAss output file */
|
||||||
|
public class AsmFile implements AsmLine {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Map<String,String> parameters;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public AsmFile(String name, Map<String, String> parameters) {
|
||||||
|
this.name = name;
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmFile(String name) {
|
||||||
|
this(name, new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmFile param(String paramName, String paramValue) {
|
||||||
|
parameters.put(paramName, paramValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLineBytes() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getLineCycles() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAsm() {
|
||||||
|
StringBuffer asm = new StringBuffer();
|
||||||
|
asm.append(".file ").append(" [ ");
|
||||||
|
asm.append("name=\"").append(name).append("\"");
|
||||||
|
for(String paramName : parameters.keySet()) {
|
||||||
|
asm.append(",");
|
||||||
|
String paramValue = parameters.get(paramName);
|
||||||
|
asm.append(paramName).append("=").append(paramValue);
|
||||||
|
}
|
||||||
|
asm.append(" ]");
|
||||||
|
return asm.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
64
src/main/java/dk/camelot64/kickc/asm/AsmSegment.java
Normal file
64
src/main/java/dk/camelot64/kickc/asm/AsmSegment.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package dk.camelot64.kickc.asm;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Selects a KickAss segment (defined using AsmSegmentDef)*/
|
||||||
|
public class AsmSegment implements AsmLine {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Map<String,String> parameters;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public AsmSegment(String name, Map<String, String> parameters) {
|
||||||
|
this.name = name;
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmSegment(String name) {
|
||||||
|
this(name, new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmSegment param(String paramName, String paramValue) {
|
||||||
|
parameters.put(paramName, paramValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLineBytes() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getLineCycles() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAsm() {
|
||||||
|
StringBuffer asm = new StringBuffer();
|
||||||
|
asm.append(".segment ").append(name);
|
||||||
|
if(parameters!=null && parameters.size()>0) {
|
||||||
|
asm.append(" [ ");
|
||||||
|
boolean first = true;
|
||||||
|
for(String paramName : parameters.keySet()) {
|
||||||
|
if(!first) asm.append(",");
|
||||||
|
first = false;
|
||||||
|
String paramValue = parameters.get(paramName);
|
||||||
|
asm.append(paramName).append("=").append(paramValue);
|
||||||
|
}
|
||||||
|
asm.append(" ]");
|
||||||
|
}
|
||||||
|
return asm.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
61
src/main/java/dk/camelot64/kickc/asm/AsmSegmentDef.java
Normal file
61
src/main/java/dk/camelot64/kickc/asm/AsmSegmentDef.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package dk.camelot64.kickc.asm;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Define a KickAss segment */
|
||||||
|
public class AsmSegmentDef implements AsmLine {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Map<String,String> parameters;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public AsmSegmentDef(String name, Map<String, String> parameters) {
|
||||||
|
this.name = name;
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmSegmentDef(String name) {
|
||||||
|
this(name, new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmSegmentDef param(String paramName, String paramValue) {
|
||||||
|
parameters.put(paramName, paramValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLineBytes() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getLineCycles() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAsm() {
|
||||||
|
StringBuffer asm = new StringBuffer();
|
||||||
|
asm.append(".segmentdef ").append(name).append(" [ ");
|
||||||
|
boolean first = true;
|
||||||
|
for(String paramName : parameters.keySet()) {
|
||||||
|
if(!first) asm.append(",");
|
||||||
|
first = false;
|
||||||
|
String paramValue = parameters.get(paramName);
|
||||||
|
asm.append(paramName).append("=").append(paramValue);
|
||||||
|
}
|
||||||
|
asm.append(" ]");
|
||||||
|
return asm.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package dk.camelot64.kickc.asm;
|
package dk.camelot64.kickc.asm;
|
||||||
|
|
||||||
import dk.camelot64.kickc.fragment.AsmFormat;
|
|
||||||
|
|
||||||
/** Set the program counter */
|
/** Set the program counter */
|
||||||
public class AsmSetPc implements AsmLine {
|
public class AsmSetPc implements AsmLine {
|
||||||
|
|
||||||
|
@ -6,8 +6,12 @@ package dk.camelot64.kickc.model;
|
|||||||
public enum TargetPlatform {
|
public enum TargetPlatform {
|
||||||
/** Commodore 64 with BASIC upstart SYS-command. */
|
/** Commodore 64 with BASIC upstart SYS-command. */
|
||||||
C64BASIC("c64basic"),
|
C64BASIC("c64basic"),
|
||||||
|
/** Commodore 64 with BASIC upstart SYS-command - using Code and Data segments. */
|
||||||
|
C64BASIC_SEGMENTS("c64basic_segments"),
|
||||||
/** 6502 assembler (with no upstart code.)*/
|
/** 6502 assembler (with no upstart code.)*/
|
||||||
ASM6502("asm6502");
|
ASM6502("asm6502"),
|
||||||
|
/** 6502 assembler (with no upstart code.)*/
|
||||||
|
ASM6502_SEGMENTS("asm6502_segments");
|
||||||
|
|
||||||
/** The default target platform. */
|
/** The default target platform. */
|
||||||
public static final TargetPlatform DEFAULT = C64BASIC;
|
public static final TargetPlatform DEFAULT = C64BASIC;
|
||||||
|
@ -84,16 +84,41 @@ public class Pass4CodeGeneration {
|
|||||||
if(TargetPlatform.C64BASIC.equals(program.getTargetPlatform())) {
|
if(TargetPlatform.C64BASIC.equals(program.getTargetPlatform())) {
|
||||||
programPc = 0x080d;
|
programPc = 0x080d;
|
||||||
} else {
|
} else {
|
||||||
programPc = 0x1000;
|
programPc = 0x2000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asm.startChunk(currentScope, null, "Upstart");
|
asm.startChunk(currentScope, null, "Upstart");
|
||||||
if(TargetPlatform.C64BASIC.equals(program.getTargetPlatform())) {
|
if(TargetPlatform.C64BASIC_SEGMENTS.equals(program.getTargetPlatform())) {
|
||||||
|
useSegments = true;
|
||||||
|
currentCodeSegmentName = "Code";
|
||||||
|
currentDataSegmentName = "Data";
|
||||||
|
asm.addLine(new AsmFile(program.getFileName() + ".prg").param("type", "\"prg\"").param("segments", "\"Program\""));
|
||||||
|
asm.addLine(new AsmSegmentDef("Program").param("segments", "\"Basic,Code,Data\""));
|
||||||
|
asm.addLine(new AsmSegmentDef("Basic").param("start", "$0801"));
|
||||||
|
asm.addLine(new AsmSegmentDef("Code").param("start", AsmFormat.getAsmNumber(programPc)));
|
||||||
|
asm.addLine(new AsmSegmentDef("Data").param("startAfter", "\"Code\""));
|
||||||
|
asm.addLine(new AsmSegment("Basic"));
|
||||||
|
asm.addLine(new AsmBasicUpstart("bbegin"));
|
||||||
|
setCurrentSegment(currentCodeSegmentName, asm);
|
||||||
|
} else if(TargetPlatform.ASM6502_SEGMENTS.equals(program.getTargetPlatform())) {
|
||||||
|
useSegments = true;
|
||||||
|
currentCodeSegmentName = "Code";
|
||||||
|
currentDataSegmentName = "Data";
|
||||||
|
asm.addLine(new AsmFile(program.getFileName() + ".prg").param("type", "\"prg\"").param("segments", "\"Program\""));
|
||||||
|
asm.addLine(new AsmSegmentDef("Program").param("segments", "\"Code,Data\""));
|
||||||
|
asm.addLine(new AsmSegmentDef("Code").param("start", AsmFormat.getAsmNumber(programPc)));
|
||||||
|
asm.addLine(new AsmSegmentDef("Data").param("startAfter", "\"Code\""));
|
||||||
|
setCurrentSegment(currentCodeSegmentName, asm);
|
||||||
|
} else if(TargetPlatform.ASM6502.equals(program.getTargetPlatform())) {
|
||||||
|
useSegments = false;
|
||||||
|
asm.addLine(new AsmSetPc("Program", AsmFormat.getAsmNumber(programPc)));
|
||||||
|
} else if(TargetPlatform.C64BASIC.equals(program.getTargetPlatform())) {
|
||||||
|
useSegments = false;
|
||||||
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"));
|
||||||
|
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.startChunk(currentScope, null, "Global Constants & labels");
|
asm.startChunk(currentScope, null, "Global Constants & labels");
|
||||||
@ -104,6 +129,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();
|
||||||
|
setCurrentSegment(currentCodeSegmentName, asm);
|
||||||
asm.startChunk(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)) {
|
||||||
@ -120,7 +146,6 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateComments(asm, block.getComments());
|
generateComments(asm, block.getComments());
|
||||||
|
|
||||||
// Generate entry points (if needed)
|
// Generate entry points (if needed)
|
||||||
genBlockEntryPoints(asm, block);
|
genBlockEntryPoints(asm, block);
|
||||||
|
|
||||||
@ -160,6 +185,9 @@ public class Pass4CodeGeneration {
|
|||||||
|
|
||||||
currentScope = ScopeRef.ROOT;
|
currentScope = ScopeRef.ROOT;
|
||||||
asm.startChunk(currentScope, null, "File Data");
|
asm.startChunk(currentScope, null, "File Data");
|
||||||
|
if(hasData(currentScope)) {
|
||||||
|
setCurrentSegment(currentDataSegmentName, asm);
|
||||||
|
}
|
||||||
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()) {
|
||||||
@ -181,6 +209,28 @@ public class Pass4CodeGeneration {
|
|||||||
program.setAsm(asm);
|
program.setAsm(asm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should the generated program use segments?
|
||||||
|
boolean useSegments = false;
|
||||||
|
// Name of the current data segment
|
||||||
|
private String currentCodeSegmentName = "Code";
|
||||||
|
// Name of the current code segment
|
||||||
|
private String currentDataSegmentName = "Data";
|
||||||
|
// Name of the current active segment
|
||||||
|
private String currentSegmentName = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current ASM segment - if needed
|
||||||
|
*
|
||||||
|
* @param segmentName The segment name we want
|
||||||
|
* @param asm The ASM program (where a .segment line is added if needed)
|
||||||
|
*/
|
||||||
|
private void setCurrentSegment(String segmentName, AsmProgram asm) {
|
||||||
|
if(useSegments && !currentSegmentName.equals(segmentName)) {
|
||||||
|
asm.addLine(new AsmSegment(segmentName));
|
||||||
|
currentSegmentName = segmentName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ASM names of variables being used for indirect calls in the current scope (procedure).
|
* ASM names of variables being used for indirect calls in the current scope (procedure).
|
||||||
* These will all be added as indirect JMP's at the end of the procedure scope.
|
* These will all be added as indirect JMP's at the end of the procedure scope.
|
||||||
@ -201,6 +251,9 @@ public class Pass4CodeGeneration {
|
|||||||
asm.addInstruction("jmp", AsmAddressingMode.IND, indirectCallAsmName, false);
|
asm.addInstruction("jmp", AsmAddressingMode.IND, indirectCallAsmName, false);
|
||||||
}
|
}
|
||||||
indirectCallAsmNames = new ArrayList<>();
|
indirectCallAsmNames = new ArrayList<>();
|
||||||
|
if(hasData(currentScope)) {
|
||||||
|
setCurrentSegment(currentDataSegmentName, asm);
|
||||||
|
}
|
||||||
addData(asm, currentScope);
|
addData(asm, currentScope);
|
||||||
asm.addScopeEnd();
|
asm.addScopeEnd();
|
||||||
}
|
}
|
||||||
@ -391,6 +444,23 @@ public class Pass4CodeGeneration {
|
|||||||
return useLabel;
|
return useLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examine whether there are any data directives to be added
|
||||||
|
*
|
||||||
|
* @param scopeRef The scope
|
||||||
|
*/
|
||||||
|
private boolean hasData(ScopeRef scopeRef) {
|
||||||
|
Scope scope = program.getScope().getScope(scopeRef);
|
||||||
|
Collection<ConstantVar> scopeConstants = scope.getAllConstants(false);
|
||||||
|
for(ConstantVar constantVar : scopeConstants) {
|
||||||
|
if(hasData(constantVar)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add data directives for constants declarations
|
* Add data directives for constants declarations
|
||||||
*
|
*
|
||||||
@ -952,8 +1022,8 @@ public class Pass4CodeGeneration {
|
|||||||
* @param encodings The encodings to ensure
|
* @param encodings The encodings to ensure
|
||||||
*/
|
*/
|
||||||
private void ensureEncoding(AsmProgram asm, Collection<ConstantString.Encoding> encodings) {
|
private void ensureEncoding(AsmProgram asm, Collection<ConstantString.Encoding> encodings) {
|
||||||
if(encodings == null || encodings.size()==0) return;
|
if(encodings == null || encodings.size() == 0) return;
|
||||||
if(encodings.size()>1) {
|
if(encodings.size() > 1) {
|
||||||
throw new CompileError("Different character encodings in one ASM statement not supported!");
|
throw new CompileError("Different character encodings in one ASM statement not supported!");
|
||||||
}
|
}
|
||||||
// Size is 1 - grab it!
|
// Size is 1 - grab it!
|
||||||
@ -1002,7 +1072,6 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get phi transitions for a specific to-block.
|
* Get phi transitions for a specific to-block.
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.asm.*;
|
import dk.camelot64.kickc.asm.*;
|
||||||
|
import dk.camelot64.kickc.fragment.AsmFormat;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -34,7 +35,7 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization {
|
|||||||
currentLabel = ((AsmLabel) line).getLabel();
|
currentLabel = ((AsmLabel) line).getLabel();
|
||||||
} else if(line instanceof AsmComment || line instanceof AsmConstant || line instanceof AsmLabelDecl) {
|
} else if(line instanceof AsmComment || line instanceof AsmConstant || line instanceof AsmLabelDecl) {
|
||||||
// ignore
|
// ignore
|
||||||
} else if(line instanceof AsmBasicUpstart || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || line instanceof AsmSetPc || line instanceof AsmInlineKickAsm|| line instanceof AsmSetEncoding|| line instanceof AsmDataKickAsm) {
|
} else if(line instanceof AsmBasicUpstart || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || line instanceof AsmSetPc || line instanceof AsmInlineKickAsm|| line instanceof AsmSetEncoding|| line instanceof AsmDataKickAsm|| line instanceof AsmSegmentDef|| line instanceof AsmSegment|| line instanceof AsmFile) {
|
||||||
currentLabel = null;
|
currentLabel = null;
|
||||||
} else if(line instanceof AsmInstruction) {
|
} else if(line instanceof AsmInstruction) {
|
||||||
if(currentLabel != null) {
|
if(currentLabel != null) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
byte[15] fibs = $1100;
|
byte[15] fibs;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fibs[0] = 0;
|
fibs[0] = 0;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
.pc = $801 "Basic"
|
.pc = $801 "Basic"
|
||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
.label fibs = $1100
|
|
||||||
main: {
|
main: {
|
||||||
lda #0
|
lda #0
|
||||||
sta fibs
|
sta fibs
|
||||||
@ -18,3 +17,4 @@ main: {
|
|||||||
bcc b1
|
bcc b1
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
fibs: .fill $f, 0
|
||||||
|
@ -2,7 +2,7 @@ Culled Empty Block (label) main::@2
|
|||||||
|
|
||||||
CONTROL FLOW GRAPH SSA
|
CONTROL FLOW GRAPH SSA
|
||||||
@begin: scope:[] from
|
@begin: scope:[] from
|
||||||
(byte[$f]) fibs#0 ← ((byte[$f])) (number) $1100
|
(byte[$f]) fibs#0 ← { fill( $f, 0) }
|
||||||
to:@1
|
to:@1
|
||||||
main: scope:[main] from @1
|
main: scope:[main] from @1
|
||||||
*((byte[$f]) fibs#0 + (number) 0) ← (number) 0
|
*((byte[$f]) fibs#0 + (number) 0) ← (number) 0
|
||||||
@ -59,12 +59,10 @@ Adding number conversion cast (unumber) 1 in (number~) main::$1 ← (byte) main:
|
|||||||
Adding number conversion cast (unumber) main::$1 in (number~) main::$1 ← (byte) main::i#2 + (unumber)(number) 1
|
Adding number conversion cast (unumber) main::$1 in (number~) main::$1 ← (byte) main::i#2 + (unumber)(number) 1
|
||||||
Adding number conversion cast (unumber) $f in (bool~) main::$3 ← (byte) main::i#1 < (number) $f
|
Adding number conversion cast (unumber) $f in (bool~) main::$3 ← (byte) main::i#1 < (number) $f
|
||||||
Successful SSA optimization PassNAddNumberTypeConversions
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
Inlining cast (byte[$f]) fibs#0 ← (byte[$f])(number) $1100
|
|
||||||
Inlining cast *((byte[$f]) fibs#0 + (unumber)(number) 0) ← (unumber)(number) 0
|
Inlining cast *((byte[$f]) fibs#0 + (unumber)(number) 0) ← (unumber)(number) 0
|
||||||
Inlining cast *((byte[$f]) fibs#0 + (unumber)(number) 1) ← (unumber)(number) 1
|
Inlining cast *((byte[$f]) fibs#0 + (unumber)(number) 1) ← (unumber)(number) 1
|
||||||
Inlining cast (byte) main::i#0 ← (unumber)(number) 0
|
Inlining cast (byte) main::i#0 ← (unumber)(number) 0
|
||||||
Successful SSA optimization Pass2InlineCast
|
Successful SSA optimization Pass2InlineCast
|
||||||
Simplifying constant pointer cast (byte*) 4352
|
|
||||||
Simplifying constant integer cast 0
|
Simplifying constant integer cast 0
|
||||||
Simplifying constant integer cast 0
|
Simplifying constant integer cast 0
|
||||||
Simplifying constant integer cast 1
|
Simplifying constant integer cast 1
|
||||||
@ -87,7 +85,9 @@ Inferred type updated to byte in (unumber~) main::$0 ← (byte) main::i#2 + (byt
|
|||||||
Inferred type updated to byte in (unumber~) main::$1 ← (byte) main::i#2 + (byte) 1
|
Inferred type updated to byte in (unumber~) main::$1 ← (byte) main::i#2 + (byte) 1
|
||||||
Simple Condition (bool~) main::$3 [11] if((byte) main::i#1<(byte) $f) goto main::@1
|
Simple Condition (bool~) main::$3 [11] if((byte) main::i#1<(byte) $f) goto main::@1
|
||||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||||
Constant (const byte[$f]) fibs#0 = (byte*) 4352
|
Constant right-side identified [0] (byte[$f]) fibs#0 ← { fill( $f, 0) }
|
||||||
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||||
|
Constant (const byte[$f]) fibs#0 = { fill( $f, 0) }
|
||||||
Constant (const byte) main::i#0 = 0
|
Constant (const byte) main::i#0 = 0
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Simplifying expression containing zero fibs#0 in [1] *((const byte[$f]) fibs#0 + (byte) 0) ← (byte) 0
|
Simplifying expression containing zero fibs#0 in [1] *((const byte[$f]) fibs#0 + (byte) 0) ← (byte) 0
|
||||||
@ -169,7 +169,6 @@ Target platform is c64basic
|
|||||||
:BasicUpstart(bbegin)
|
:BasicUpstart(bbegin)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
.label fibs = $1100
|
|
||||||
// @begin
|
// @begin
|
||||||
bbegin:
|
bbegin:
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
@ -229,6 +228,7 @@ main: {
|
|||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
|
fibs: .fill $f, 0
|
||||||
|
|
||||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
Statement [4] *((const byte[$f]) fibs#0) ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
Statement [4] *((const byte[$f]) fibs#0) ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||||
@ -255,7 +255,6 @@ ASSEMBLER BEFORE OPTIMIZATION
|
|||||||
:BasicUpstart(bbegin)
|
:BasicUpstart(bbegin)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
.label fibs = $1100
|
|
||||||
// @begin
|
// @begin
|
||||||
bbegin:
|
bbegin:
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
@ -307,6 +306,7 @@ main: {
|
|||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
|
fibs: .fill $f, 0
|
||||||
|
|
||||||
ASSEMBLER OPTIMIZATIONS
|
ASSEMBLER OPTIMIZATIONS
|
||||||
Removing instruction jmp b1
|
Removing instruction jmp b1
|
||||||
@ -337,7 +337,7 @@ FINAL SYMBOL TABLE
|
|||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
(byte[$f]) fibs
|
(byte[$f]) fibs
|
||||||
(const byte[$f]) fibs#0 fibs = (byte*) 4352
|
(const byte[$f]) fibs#0 fibs = { fill( $f, 0) }
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(byte~) main::$2 reg byte a 22.0
|
(byte~) main::$2 reg byte a 22.0
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
@ -359,7 +359,6 @@ Score: 263
|
|||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
.label fibs = $1100
|
|
||||||
// @begin
|
// @begin
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
// @1
|
// @1
|
||||||
@ -403,4 +402,5 @@ main: {
|
|||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
|
fibs: .fill $f, 0
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
(byte[$f]) fibs
|
(byte[$f]) fibs
|
||||||
(const byte[$f]) fibs#0 fibs = (byte*) 4352
|
(const byte[$f]) fibs#0 fibs = { fill( $f, 0) }
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(byte~) main::$2 reg byte a 22.0
|
(byte~) main::$2 reg byte a 22.0
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Tests the target platform ASM6502
|
// Tests the target platform ASM6502
|
||||||
.pc = $1000 "Program"
|
.pc = $2000 "Program"
|
||||||
main: {
|
main: {
|
||||||
ldx #0
|
ldx #0
|
||||||
b2:
|
b2:
|
||||||
|
@ -143,7 +143,7 @@ Target platform is asm6502
|
|||||||
// File Comments
|
// File Comments
|
||||||
// Tests the target platform ASM6502
|
// Tests the target platform ASM6502
|
||||||
// Upstart
|
// Upstart
|
||||||
.pc = $1000 "Program"
|
.pc = $2000 "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
// @begin
|
// @begin
|
||||||
bbegin:
|
bbegin:
|
||||||
@ -212,7 +212,7 @@ ASSEMBLER BEFORE OPTIMIZATION
|
|||||||
// File Comments
|
// File Comments
|
||||||
// Tests the target platform ASM6502
|
// Tests the target platform ASM6502
|
||||||
// Upstart
|
// Upstart
|
||||||
.pc = $1000 "Program"
|
.pc = $2000 "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
// @begin
|
// @begin
|
||||||
bbegin:
|
bbegin:
|
||||||
@ -311,7 +311,7 @@ Score: 161
|
|||||||
// File Comments
|
// File Comments
|
||||||
// Tests the target platform ASM6502
|
// Tests the target platform ASM6502
|
||||||
// Upstart
|
// Upstart
|
||||||
.pc = $1000 "Program"
|
.pc = $2000 "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
// @begin
|
// @begin
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
Loading…
Reference in New Issue
Block a user