1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Renamed fragment system classes in prepararion of graph based solution.

This commit is contained in:
jespergravgaard 2018-01-02 14:13:08 +01:00
parent 2084be92e0
commit 3595db56db
23 changed files with 743 additions and 708 deletions

View File

@ -10,7 +10,7 @@ import java.util.ArrayList;
import java.util.Map;
/** ASM Code Fragment with register/variable bindings that can be used for generating ASM code for a specific statement . */
public class AsmFragment {
public class AsmFragmentInstance {
/** The symbol table. */
private Program program;
@ -27,7 +27,7 @@ public class AsmFragment {
/** The scope containing the fragment. Used when referencing symbols defined in other scopes. */
private ScopeRef codeScopeRef;
public AsmFragment(
public AsmFragmentInstance(
Program program,
String name,
ScopeRef codeScopeRef,
@ -134,9 +134,9 @@ public class AsmFragment {
private String name;
private AsmProgram program;
private AsmFragment bindings;
private AsmFragmentInstance bindings;
public AsmSequenceGenerator(String name, AsmFragment bindings, AsmProgram program) {
public AsmSequenceGenerator(String name, AsmFragmentInstance bindings, AsmProgram program) {
this.name = name;
this.bindings = bindings;
this.program = program;

View File

@ -6,9 +6,9 @@ import java.util.LinkedHashMap;
import java.util.Map;
/**
* A fragment signature generated from a {@link Statement} used to load/synthesize an AsmFragent for creating ASM code for the statement
* A fragment specification generated from a {@link Statement} used to load/synthesize an {@link AsmFragmentInstance} for creating ASM code for the statement
*/
public class AsmFragmentSignature {
public class AsmFragmentInstanceSpec {
/**
* The symbol table.
@ -16,7 +16,7 @@ public class AsmFragmentSignature {
private Program program;
/**
* The string signature/name of the fragment fragment.
* The string signature/name of the fragment template.
*/
private String signature;
@ -37,7 +37,7 @@ public class AsmFragmentSignature {
private int nextConstByteIdx = 1;
private int nextLabelIdx = 1;
public AsmFragmentSignature(
public AsmFragmentInstanceSpec(
StatementConditionalJump conditionalJump,
ControlFlowBlock block,
Program program,
@ -49,7 +49,7 @@ public class AsmFragmentSignature {
setSignature(conditionalJumpSignature);
}
public AsmFragmentSignature(StatementAssignment assignment, Program program) {
public AsmFragmentInstanceSpec(StatementAssignment assignment, Program program) {
this.codeScopeRef = program.getStatementInfos().getBlock(assignment).getScope();
this.bindings = new LinkedHashMap<>();
this.program = program;
@ -60,14 +60,14 @@ public class AsmFragmentSignature {
assignment.getrValue2()));
}
public AsmFragmentSignature(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) {
public AsmFragmentInstanceSpec(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) {
this.codeScopeRef = codeScopeRef;
this.bindings = new LinkedHashMap<>();
this.program = program;
setSignature(assignmentSignature(lValue, null, null, rValue));
}
public AsmFragmentSignature(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) {
public AsmFragmentInstanceSpec(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) {
this.codeScopeRef = program.getStatementInfos().getBlock(assignment).getScope();
this.bindings = new LinkedHashMap<>();
this.program = program;
@ -81,14 +81,14 @@ public class AsmFragmentSignature {
private String assignmentWithAluSignature(StatementAssignment assignment, StatementAssignment assignmentAlu) {
this.codeScopeRef = program.getStatementInfos().getBlock(assignment).getScope();
if(!(assignment.getrValue2() instanceof VariableRef)) {
throw new AsmFragment.AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
throw new AsmFragmentInstance.AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
}
VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2();
Variable assignmentRValue2Var = program.getSymbolInfos().getVariable(assignmentRValue2);
Registers.Register rVal2Register = assignmentRValue2Var.getAllocation();
if(!rVal2Register.getType().equals(Registers.RegisterType.REG_ALU)) {
throw new AsmFragment.AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
throw new AsmFragmentInstance.AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
}
StringBuilder signature = new StringBuilder();
signature.append(bind(assignment.getlValue()));
@ -309,7 +309,7 @@ public class AsmFragmentSignature {
} else if(Registers.RegisterType.REG_Y_BYTE.equals(register.getType())) {
return "yy";
} else if(Registers.RegisterType.REG_ALU.equals(register.getType())) {
throw new AsmFragment.AluNotApplicableException();
throw new AsmFragmentInstance.AluNotApplicableException();
} else {
throw new RuntimeException("Not implemented " + register.getType());
}
@ -363,4 +363,24 @@ public class AsmFragmentSignature {
str.append(") ");
return str.toString();
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
AsmFragmentInstanceSpec that = (AsmFragmentInstanceSpec) o;
if(signature != null ? !signature.equals(that.signature) : that.signature != null) return false;
if(bindings != null ? !bindings.equals(that.bindings) : that.bindings != null) return false;
return codeScopeRef != null ? codeScopeRef.equals(that.codeScopeRef) : that.codeScopeRef == null;
}
@Override
public int hashCode() {
int result = signature != null ? signature.hashCode() : 0;
result = 31 * result + (bindings != null ? bindings.hashCode() : 0);
result = 31 * result + (codeScopeRef != null ? codeScopeRef.hashCode() : 0);
return result;
}
}

View File

@ -1,562 +0,0 @@
package dk.camelot64.kickc.fragment;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmProgram;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
/**
* Provides fragments from their signature.
* <p>
* The first priority is loading a fragment file from the fragment-folder.
* If no fragment file is found for the signature the manager attempts to synthesise a fragment from another fragment.
*/
public class AsmFragmentManager {
/** Cache for the best fragment templates. Maps signature to the best fragment template for the signature. */
private static Map<String, AsmFragmentTemplate> bestFragmentCache = new HashMap<>();
/** Caches all asm fragment templates for all encountered signatures. */
private static Map<String, List<AsmFragmentTemplate>> fragmentTemplateCache = new LinkedHashMap<>();
/** Special singleton representing that the fragment can not be synthesized or loaded. */
private static AsmFragmentTemplate UNKNOWN = new AsmFragmentTemplate("UNKNOWN", null);
/**
* All the synthesize rules available.
*/
private static List<AsmFragmentSynthesis> fragmentSyntheses;
static Map<String, List<AsmFragmentTemplate>> getFragmentTemplateCache() {
return fragmentTemplateCache;
}
public static AsmFragment getFragment(AsmFragmentSignature signature, CompileLog log) {
AsmFragmentTemplate bestTemplate = bestFragmentCache.get(signature.getSignature());
if(bestTemplate == UNKNOWN) {
if(log.isVerboseFragmentLog()) {
log.append("Unknown fragment " + signature.getSignature());
}
throw new UnknownFragmentException(signature.getSignature());
}
if(bestTemplate == null) {
AsmFragmentTemplateSynthesizer synthesizer = new AsmFragmentTemplateSynthesizer(signature.getSignature(), log);
List<AsmFragmentTemplate> candidates = synthesizer.loadOrSynthesizeFragment(signature.getSignature(), new AsmSynthesisPath());
if(candidates.size() == 0) {
if(log.isVerboseFragmentLog()) {
log.append("Unknown fragment " + signature.toString());
}
bestFragmentCache.put(signature.getSignature(), UNKNOWN);
throw new UnknownFragmentException(signature.getSignature());
}
double minScore = Double.MAX_VALUE;
double maxScore = Double.MIN_VALUE;
AsmFragmentTemplate maxTemplate = null;
for(AsmFragmentTemplate candidateTemplate : candidates) {
AsmFragment candidateFragment = new AsmFragment(
signature.getProgram(),
signature.getSignature(),
signature.getCodeScope(),
candidateTemplate,
signature.getBindings());
AsmProgram candidateAsm = new AsmProgram();
candidateAsm.startSegment(null, signature.toString());
candidateFragment.generate(candidateAsm);
double score = candidateAsm.getCycles();
if(score < minScore) {
minScore = score;
bestTemplate = candidateTemplate;
}
if(score > maxScore) {
maxScore = score;
maxTemplate = candidateTemplate;
}
}
if(log.isVerboseFragmentLog()) {
log.append("Found fragment " + bestTemplate.getName() + " score: " + minScore + " from " + candidates.size() + " candidates");
}
bestFragmentCache.put(signature.getSignature(), bestTemplate);
}
// Count usages
AsmFragmentUsages.incUsage(bestTemplate);
// Return the resulting fragment instance
return new AsmFragment(
signature.getProgram(),
signature.getSignature(),
signature.getCodeScope(),
bestTemplate,
signature.getBindings());
}
/**
* Look for a fragment on the disk.
*
* @param signature The fragment signature
* @return The fragment file contents. Null if the fragment is not on the disk.
*/
private static CharStream loadFragment(String signature) {
ClassLoader classLoader = AsmFragmentManager.class.getClassLoader();
URL fragmentUrl = classLoader.getResource("dk/camelot64/kickc/fragment/asm/" + signature + ".asm");
if(fragmentUrl == null) {
return null;
}
try {
InputStream fragmentStream = fragmentUrl.openStream();
return CharStreams.fromStream(fragmentStream);
} catch(IOException e) {
throw new RuntimeException("Error loading fragment file " + fragmentUrl);
}
}
static File[] allFragmentFiles() {
ClassLoader classLoader = AsmFragmentManager.class.getClassLoader();
String path = classLoader.getResource("dk/camelot64/kickc/fragment/asm/").getPath();
return new File(path).listFiles((dir, name) -> name.endsWith(".asm"));
}
private static List<AsmFragmentSynthesis> getFragmentSyntheses() {
if(fragmentSyntheses == null) {
fragmentSyntheses = initFragmentSyntheses();
}
return fragmentSyntheses;
}
private static List<AsmFragmentSynthesis> initFragmentSyntheses() {
Map<String, String> mapZ = new LinkedHashMap<>();
mapZ.put("z2", "z1");
mapZ.put("z3", "z2");
Map<String, String> mapZ2 = new LinkedHashMap<>();
mapZ2.put("z3", "z1");
Map<String, String> mapZ3 = new LinkedHashMap<>();
mapZ3.put("z3", "z2");
Map<String, String> mapC = new LinkedHashMap<>();
mapC.put("c2", "c1");
mapC.put("c3", "c2");
Map<String, String> mapC3 = new LinkedHashMap<>();
mapC3.put("c3", "c2");
Map<String, String> mapZC = new LinkedHashMap<>();
mapZC.putAll(mapZ);
mapZC.putAll(mapC);
Map<String, String> mapSToU = new LinkedHashMap<>();
mapSToU.put("vbsz1", "vbuz1");
mapSToU.put("vbsz2", "vbuz2");
mapSToU.put("vbsz3", "vbuz3");
mapSToU.put("vbsc1", "vbuc1");
mapSToU.put("vbsc2", "vbuc2");
mapSToU.put("vbsc3", "vbuc3");
mapSToU.put("vbsaa", "vbuaa");
mapSToU.put("vbsxx", "vbuxx");
mapSToU.put("vbsyy", "vbuyy");
mapSToU.put("vwsz1", "vwuz1");
mapSToU.put("vwsz2", "vwuz2");
mapSToU.put("vwsz3", "vwuz3");
mapSToU.put("vwsc1", "vwuc1");
mapSToU.put("vwsc2", "vwuc2");
mapSToU.put("vwsc3", "vwuc3");
List<AsmFragmentSynthesis> synths = new ArrayList<>();
// NEW STYLE REWRITES - Utilizes that all combinations are tried
// Replace first AA with XX
synths.add(new AsmFragmentSynthesis("(.*vb.)aa(.*)", "...aa=.*|.*xx.*", "tax", "$1xx$2", null, null));
// Replace two AAs with XX
synths.add(new AsmFragmentSynthesis("(.*vb.)aa(.*vb.)aa(.*)", "...aa=.*|.*xx.*", "tax", "$1xx$2xx$3", null, null));
// Replace second (not first) AA with XX
synths.add(new AsmFragmentSynthesis("(.*)aa(.*vb.)aa(.*)", "...aa=.*|.*xx.*", "tax", "$1aa$2xx$3", null, null));
// Replace first AA with YY
synths.add(new AsmFragmentSynthesis("(.*vb.)aa(.*)", "...aa=.*|.*yy.*", "tay", "$1yy$2", null, null));
// Replace two AAs with YY
synths.add(new AsmFragmentSynthesis("(.*vb.)aa(.*vb.)aa(.*)", "...aa=.*|.*yy.*", "tay", "$1yy$2yy$3", null, null));
// Replace second (not first) AA with YY
synths.add(new AsmFragmentSynthesis("(.*)aa(.*vb.)aa(.*)", "...aa=.*|.*yy.*", "tay", "$1aa$2yy$3", null, null));
// Replace first XX with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)xx(.*)", "...xx=.*|.*aa.*", "txa", "$1aa$2", null, null));
// Replace two XXs with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)xx(.*vb.)xx(.*)", "...xx=.*|.*aa.*", "txa", "$1aa$2aa$3", null, null));
// Replace second (not first) XX with AA
synths.add(new AsmFragmentSynthesis("(.*)xx(.*vb.)xx(.*)", "...xx=.*|.*aa.*", "txa", "$1xx$2aa$3", null, null));
// Replace first YY with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)yy(.*)", "...yy=.*|.*aa.*", "tya", "$1aa$2", null, null));
// Replace two YYs with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)yy(.*vb.)yy(.*)", "...yy=.*|.*aa.*", "tya", "$1aa$2aa$3", null, null));
// Replace second (not first) YY with AA
synths.add(new AsmFragmentSynthesis("(.*)yy(.*vb.)yy(.*)", "...yy=.*|.*aa.*", "tya", "$1yy$2aa$3", null, null));
// Replace Z1 with AA (only one)
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*|.*aa.*", "lda {z1}", "$1aa$2", null, mapZ));
// Replace two Z1s with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*z1.*|.*aa.*", "lda {z1}", "$1aa$2aa$3", null, mapZ));
// Replace first (not second) Z1 with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*)z1(.*)", "...z1=.*|.*aa.*", "lda {z1}", "$1aa$2z1$3", null, null));
// Replace second (not first) Z1 with AA
synths.add(new AsmFragmentSynthesis("(.*)z1(.*vb.)z1(.*)", "...z1=.*|.*aa.*", "lda {z1}", "$1z1$2aa$3", null, null));
// Replace Z1 with YY (only one)
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*|.*yy.*", "ldy {z1}", "$1yy$2", null, mapZ));
// Replace two Z1s with YY
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*z1.*|.*yy.*", "ldy {z1}", "$1yy$2yy$3", null, mapZ));
// Replace first (not second) Z1 with YY
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*)z1(.*)", "...z1=.*|.*yy.*", "ldy {z1}", "$1yy$2z1$3", null, null));
// Replace second (not first) Z1 with YY
synths.add(new AsmFragmentSynthesis("(.*)z1(.*vb.)z1(.*)", "...z1=.*|.*yy.*", "ldy {z1}", "$1z1$2yy$3", null, null));
// Replace Z1 with XX (only one)
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*|.*xx.*", "ldx {z1}", "$1xx$2", null, mapZ));
// Replace two Z1s with XX
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*z1.*|.*xx.*", "ldx {z1}", "$1xx$2xx$3", null, mapZ));
// Replace first (not second) Z1 with XX
synths.add(new AsmFragmentSynthesis("(.*vb.)z1(.*)z1(.*)", "...z1=.*|.*xx.*", "ldx {z1}", "$1xx$2z1$3", null, null));
// Replace second (not first) Z1 with XX
synths.add(new AsmFragmentSynthesis("(.*)z1(.*vb.)z1(.*)", "...z1=.*|.*xx.*", "ldx {z1}", "$1z1$2xx$3", null, null));
// Replace Z2 with AA (only one)
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*|.*aa.*", "lda {z2}", "$1aa$2", null, mapZ3));
// Replace two Z2s with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*z2.*|.*aa.*", "lda {z2}", "$1aa$2aa$3", null, mapZ3));
// Replace first (of 2) Z2 with AA
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*)z2(.*)", "...z2=.*|.*aa.*", "lda {z2}", "$1aa$2z2$3", null, null));
// Replace second (of 2) Z2 with AA
synths.add(new AsmFragmentSynthesis("(.*)z2(.*vb.)z2(.*)", "...z2=.*|.*aa.*", "lda {z2}", "$1z2$2aa$3", null, null));
// Replace Z2 with YY (only one)
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*|.*yy.*", "ldy {z2}", "$1yy$2", null, mapZ3));
// Replace two Z2s with YY
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*z2.*|.*yy.*", "ldy {z2}", "$1yy$2yy$3", null, mapZ3));
// Replace first (of 2) Z2 with YY
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*)z2(.*)", "...z2=.*|.*yy.*", "ldy {z2}", "$1yy$2z2$3", null, null));
// Replace second (of 2) Z2 with YY
synths.add(new AsmFragmentSynthesis("(.*)z2(.*vb.)z2(.*)", "...z2=.*|.*yy.*", "ldy {z2}", "$1z2$2yy$3", null, null));
// Replace Z2 with XX(only one)
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*|.*xx.*", "ldx {z2}", "$1xx$2", null, mapZ3));
// Replace two Z2s with XX
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*z2.*|.*xx.*", "ldx {z2}", "$1xx$2xx$3", null, mapZ3));
// Replace first (of 2) Z2 with XX
synths.add(new AsmFragmentSynthesis("(.*vb.)z2(.*)z2(.*)", "...z2=.*|.*xx.*", "ldx {z2}", "$1xx$2z2$3", null, null));
// Replace second (of 2) Z2 with XX
synths.add(new AsmFragmentSynthesis("(.*)z2(.*vb.)z2(.*)", "...z2=.*|.*xx.*", "ldx {z2}", "$1z2$2xx$3", null, null));
// Rewrite comparisons < to >
//synths.add(new AsmFragmentSynthesis("(.*)_gt_(.*)_then_(.*)", null, null, "$2_lt_$1_then_$3", null, null));
// Rewrite comparisons > to <
//synths.add(new AsmFragmentSynthesis("(.*)_lt_(.*)_then_(.*)", null, null, "$2_gt_$1_then_$3", null, null));
// Rewrite comparisons <= to >=
//synths.add(new AsmFragmentSynthesis("(.*)_le_(.*)_then_(.*)", null, null, "$2_ge_$1_then_$3", null, null));
// Rewrite comparisons >= to <=
//synths.add(new AsmFragmentSynthesis("(.*)_ge_(.*)_then_(.*)", null, null, "$2_le_$1_then_$3", null, null));
// Rewrite comparisons swap ==
//synths.add(new AsmFragmentSynthesis("(.*)_eq_(.*)_then_(.*)", null, null, "$2_eq_$1_then_$3", null, null));
// Rewrite comparisons swap !=
//synths.add(new AsmFragmentSynthesis("(.*)_neq_(.*)_then_(.*)", null, null, "$2_neq_$1_then_$3", null, null));
// OLD STYLE REWRITES - written when only one rule could be taken
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_(band|bor|bxor|plus)_(vb.aa)", ".*=vb.aa_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_(band|bor|bxor|plus)_(vb.xx)", ".*=vb.[ax][ax]_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_(band|bor|bxor|plus)_(vb.yy)", ".*=vb.[axy][axy]_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentSynthesis("vbuxx=(.*)", null, null, "vbuaa=$1", "tax\n", null));
synths.add(new AsmFragmentSynthesis("vbsxx=(.*)", null, null, "vbsaa=$1", "tax\n", null));
synths.add(new AsmFragmentSynthesis("vbuyy=(.*)", null, null, "vbuaa=$1", "tay\n", null));
synths.add(new AsmFragmentSynthesis("vbsyy=(.*)", null, null, "vbsaa=$1", "tay\n", null));
synths.add(new AsmFragmentSynthesis("vbuz1=(.*)", ".*=.*vb.z1.*", null, "vbuaa=$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentSynthesis("vbsz1=(.*)", ".*=.*vb.z1.*", null, "vbsaa=$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentSynthesis("_deref_pb(.)c1=(.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "sta {c1}\n", mapC));
synths.add(new AsmFragmentSynthesis("_deref_pb(.)c1=(.*c1.*)", null, null, "vb$1aa=$2", "sta {c1}\n", null));
synths.add(new AsmFragmentSynthesis("_deref_pbuz1=(.*)", ".*z1.*z1.*", null, "vbuaa=$1", "ldy #0\n" + "sta ({z1}),y\n", mapZ));
synths.add(new AsmFragmentSynthesis("_deref_pbuz1=(.*z1.*)", null, null, "vbuaa=$1", "ldy #0\n" + "sta ({z1}),y\n", null));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuz1=(.*)", ".*z1.*z1.*|.*c1.*c1.*", null, "vb$1aa=$2", "ldx {z1}\n" + "sta {c1},x\n", mapZC));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuyy=(.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "sta {c1},y\n", mapC));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuxx=(.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "sta {c1},x\n", mapC));
synths.add(new AsmFragmentSynthesis("pb(.)z1_derefidx_vbuz2=(.*)", ".*z1.*z1.*|.*z2.*z2.*", null, "vb$1aa=$2", "ldy {z2}\n" + "sta ({z1}),y\n", mapZ2));
synths.add(new AsmFragmentSynthesis("(.*)=_deref_pb(.)c1(.*)", ".*=.*aa.*", "lda {c1}\n", "$1=vb$2aa$3", null, mapC));
synths.add(new AsmFragmentSynthesis("(.*)=_deref_pb(.)z1(.*)", ".*z1.*z1.*|.*=.*aa.*|.*=.*yy.*", "ldy #0\n" + "lda ({z1}),y\n", "$1=vb$2aa$3", null, mapZ));
// Convert array indexing with A register to X/Y register by prefixing tax/tay (..._derefidx_vbuaa... -> ..._derefidx_vbuxx... /... _derefidx_vbuyy... )
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*xx.*", "tax\n", "$1=$2_derefidx_vbuxx$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*yy.*", "tay\n", "$1=$2_derefidx_vbuyy$3", null, null));
// Convert array indexing with zero page to x/y register by prefixing ldx z1 / ldy z1 ( ..._derefidx_vbuzn... -> ..._derefidx_vbuxx... / ..._derefidx_vbuyy... )
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*xx.*|.*z1.*z1.*", "ldx {z1}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*yy.*|.*z1.*z1.*", "ldy {z1}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*xx.*|.*z2.*z2.*", "ldx {z2}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ3));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*yy.*|.*z2.*z2.*", "ldy {z2}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ3));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*yy.*", "ldy {z3}\n", "$1=$2_derefidx_vbuyy$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*xx.*", "ldx {z3}\n", "$1=$2_derefidx_vbuxx$3", null, null));
// Convert array indexing twice with A/zp1/zp2 to X/Y register with a ldx/ldy prefix ( ..._derefidx_vbunn..._derefidx_vbunn... -> ..._derefidx_vbuxx..._derefidx_vbuxx... )
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuaa(.*)_derefidx_vbuaa(.*)", ".*aa.*aa.*aa.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "tax\n", null));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuaa(.*)_derefidx_vbuaa(.*)", ".*aa.*aa.*aa.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "tay\n", null));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z1}\n", mapZ));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z1}\n", mapZ));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z2}\n", mapZ));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z2}\n", mapZ));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuz1=(.*c1.*)", ".*z1.*z1.*", null, "vb$1aa=$2", "ldx {z1}\n" + "sta {c1},x\n", mapZ));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuz1=(.*z1.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "ldx {z1}\n" + "sta {c1},x\n", mapC));
// Convert X/Y-based array indexing of a constant pointer into A-register by prefixing lda cn,x / lda cn,y ( ...pb.c1_derefidx_vbuxx... / ...pb.c1_derefidx_vbuyy... -> ...vb.aa... )
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new AsmFragmentSynthesis("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*c1.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new AsmFragmentSynthesis("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*c1.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new AsmFragmentSynthesis("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*c2.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new AsmFragmentSynthesis("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*c2.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
// Convert zeropage/constants/X/Y in assignments to A-register using LDA/TXA/TYA prefix
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbuz1(.*)", ".*z1.*=.*|.*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2vbuaa$3", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbsz1(.*)", ".*z1.*=.*|.*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2vbsaa$3", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbuz2(.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbuaa$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbsz2(.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbsaa$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbuz2(.*z3.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbuaa$3", null, mapZ3));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbsz2(.*z3.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbsaa$3", null, mapZ3));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbuxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbsxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbsaa", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbuyy", ".*=.*[ay][ay].*yy|.*derefidx_vb.yy", "tya\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbsyy", ".*=-*[ay][ay].*yy|.*derefidx_vb.yy", "tya\n", "$1=$2_vbsaa", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbuz1", ".*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2_vbuaa", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbsz1", ".*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2_vbsaa", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbuz2", ".*=.*aa.*|.*z2.*z2.*", "lda {z2}\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_vbuz3", ".*=.*aa.*|.*z3.*z3.*", "lda {z3}\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentSynthesis("vbuz1=vbuz1(.*)", ".*=.*vb.aa.*|.*z1.*z1.*z1.*", "lda {z1}\n", "vbuaa=vbuaa$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentSynthesis("vbsz1=vbsz1(.*)", ".*=.*vb.aa.*|.*z1.*z1.*z1.*", "lda {z1}\n", "vbsaa=vbsaa$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentSynthesis("vbuz1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*|.*z1.*z1.*", "lda {z1}\n", "vbuaa_$1_$2", null, mapZ));
synths.add(new AsmFragmentSynthesis("vbsz1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*|.*z1.*z1.*", "lda {z1}\n", "vbsaa_$1_$2", null, mapZ));
synths.add(new AsmFragmentSynthesis("_deref_pb(.)c1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*", "lda {c1}\n", "vb$1aa_$2_$3", null, mapC));
synths.add(new AsmFragmentSynthesis("_deref_pb(.)z1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*|.*vb.yy.*|.*z1.*z1.*", "ldy #0\n" + "lda ({z1}),y\n", "vb$1aa_$2_$3", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuz1_(.*)", ".*z1.*z1.*|.*.yy.*", "ldy {z1}\n", "$1_derefidx_vbuyy_$2", null, mapZ));
synths.add(new AsmFragmentSynthesis("(.*)_derefidx_vbuz1_(lt|gt|le|ge|eq|neq)_(.*)", ".*z1.*z1.*|.*vb.xx.*", "ldx {z1}\n", "$1_derefidx_vbuxx_$2_$3", null, mapZ));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuyy_(lt|gt|le|ge|eq|neq)_(.*)", ".*c1.*c1.*|.*aa.*", "lda {c1},y\n", "vb$1aa_$2_$3", null, mapC));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuyy_(lt|gt|le|ge|eq|neq)_(.*c1.*)", ".*aa.*", "lda {c1},y\n", "vb$1aa_$2_$3", null, null));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuxx_(lt|gt|le|ge|eq|neq)_(.*)", ".*c1.*c1.*|.*aa.*", "lda {c1},x\n", "vb$1aa_$2_$3", null, mapC));
synths.add(new AsmFragmentSynthesis("pb(.)c1_derefidx_vbuxx_(lt|gt|le|ge|eq|neq)_(.*c1.*)", ".*aa.*", "lda {c1},x\n", "vb$1aa_$2_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_ge_(vb.aa)_then_(.*)", ".*vb.aa.*_ge.*", null, "$2_le_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_ge_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_ge.*", null, "$2_le_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_ge_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_ge.*", null, "$2_le_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_lt_(vb.aa)_then_(.*)", ".*vb.aa.*_lt.*", null, "$2_gt_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_lt_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_lt.*", null, "$2_gt_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_lt_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_lt.*", null, "$2_gt_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_gt_(vb.aa)_then_(.*)", ".*vb.aa.*_gt.*", null, "$2_lt_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_gt_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_gt.*", null, "$2_lt_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_gt_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_gt.*", null, "$2_lt_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_le_(vb.aa)_then_(.*)", ".*vb.aa.*_le.*", null, "$2_ge_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_le_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_le.*", null, "$2_ge_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_le_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_le.*", null, "$2_ge_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_neq_(vb.aa)_then_(.*)", ".*vb.aa.*_neq.*", null, "$2_neq_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_neq_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_neq.*", null, "$2_neq_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_neq_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_neq.*", null, "$2_neq_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_eq_(vb.aa)_then_(.*)", ".*vb.aa.*_eq.*", null, "$2_eq_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_eq_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_eq.*", null, "$2_eq_$1_then_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)_eq_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_eq.*", null, "$2_eq_$1_then_$3", null, null));
// Use unsigned ASM to synthesize signed ASM ( ...vbs... -> ...vbu... )
synths.add(new AsmFragmentSynthesis("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_(eq|neq)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_then_(.*)", null, null, "$1_$2_$3_then_$4", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_(plus|band|bxor|bor)_(vbsz.|csoby.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2_$3_$4", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)=_(inc|dec)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=_$2_$3", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(vwsz.|vwsc.)_(eq|neq)_(vwsz.|vwsc.)_then_(.*)", null, null, "$1_$2_$3_then_$4", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(vwsz.)=(vwsz.|vwsc.)", null, null, "$1=$2", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(v.sz.)=(v.s..)_(band|bxor|bor)_(v.s..)", null, null, "$1=$2_$3_$4", null, mapSToU));
synths.add(new AsmFragmentSynthesis("(vbuz.|vbuaa|vbuxx|vbuyy)=_(lo|hi)_vws(z.|c.)", null, null, "$1=_$2_vwu$3", null, mapSToU));
// Use constant word ASM to synthesize unsigned constant byte ASM ( ...vb.c... -> vw.c... )
synths.add(new AsmFragmentSynthesis("(vwuz.)=(vwuz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwuc$4", null, null));
synths.add(new AsmFragmentSynthesis("(vwuz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwuz.)", null, null, "$1=vwuc$2_$3_$4", null, null));
synths.add(new AsmFragmentSynthesis("(vwsz.)=(vwsz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwsc$4", null, null));
synths.add(new AsmFragmentSynthesis("(vwsz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwsz.)", null, null, "$1=vwsc$2_$3_$4", null, null));
// Move constant words to the end of the ASM signature for symmetric operators ( ...vw.c...vw.z... -> ...vw.z...vw.c... )
synths.add(new AsmFragmentSynthesis("(vwuz.)=(vwuc.)_(plus|band|bxor|bor)_(vwuz.)", null, null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentSynthesis("(vwsz.)=(vwsc.)_(plus|band|bxor|bor)_(vwsz.)", null, null, "$1=$4_$3_$2", null, null));
// Use Z1/Z2 ASM to synthesize Z1-only code ( ...z1...z1... -> ...z1...z2... )
synths.add(new AsmFragmentSynthesis("(v..)z1=(v..)z1_(plus|minus|band|bxor|bor)_(.*)", ".*z2.*", null, "$1z1=$2z2_$3_$4", null, mapZ, false));
synths.add(new AsmFragmentSynthesis("(v..)z1=(.*)_(plus|minus|band|bxor|bor)_(v..)z1", ".*z2.*", null, "$1z1=$2_$3_$4z2", null, mapZ, false));
synths.add(new AsmFragmentSynthesis("(v..)z1=_(neg|lo|hi)_(v..)z1", ".*z2.*", null, "$1z1=_$2_$3z2", null, mapZ, false));
// Convert INC/DEC to +1/-1 ( ..._inc_xxx... -> ...xxx_plus_1_... / ..._dec_xxx... -> ...xxx_minus_1_... )
synths.add(new AsmFragmentSynthesis("vb(.)aa=_inc_(.*)", null, null, "vb$1aa=$2_plus_1", null, null));
synths.add(new AsmFragmentSynthesis("vb(.)aa=_dec_(.*)", null, null, "vb$1aa=$2_minus_1", null, null));
// Synthesize XX/YY using AA
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbuxx(.*)", ".*=.*aa.*|.*derefidx_vb.xx.*", "txa\n", "$1=$2vbuaa$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbsxx(.*)", ".*=.*aa.*|.*derefidx_vb.xx.*", "txa\n", "$1=$2vbsaa$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbuyy(.*)", ".*=.*aa.*|.*derefidx_vb.yy.*", "tya\n", "$1=$2vbuaa$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbsyy(.*)", ".*=.*aa.*|.*derefidx_vb.yy.*", "tya\n", "$1=$2vbsaa$3", null, null));
// Synthesize constants using AA
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbuc1(.*)", ".*=.*aa.*|.*c1.*c1.*|.*c1_deref.*", "lda #{c1}\n", "$1=$2vbuaa$3", null, mapC));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)vbsc1(.*)", ".*=.*aa.*|.*c1.*c1.*|.*c1_deref.*", "lda #{c1}\n", "$1=$2vbsaa$3", null, mapC));
// Synthesize some constant pointers as constant words
synths.add(new AsmFragmentSynthesis("(.*)_(lt|gt|le|ge|eq|neq)_p..([cz].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null));
synths.add(new AsmFragmentSynthesis("p..([cz].)_(lt|gt|le|ge|eq|neq)_(.*)", null, null, "vwu$1_$2_$3", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=p..([zc].)", null, null, "$1=vwu$2", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=(.*)_(plus|minus|bor|bxor)_p..([cz].)", null, null, "$1=$2_$3_vwu$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=p..([cz].)_(plus|minus|bor|bxor)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
synths.add(new AsmFragmentSynthesis("p..([cz].)=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwu$1=$2_$3_$4", null, null));
synths.add(new AsmFragmentSynthesis("(.*)=p..([cz].)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
return synths;
}
/**
* The synthesis path describes the different signatures being attempted to synthesize a fragment.
* Used to avoid infinite loops during synthesis.
*/
static class AsmSynthesisPath {
private ArrayDeque<String> signatures;
public AsmSynthesisPath() {
this.signatures = new ArrayDeque<>();
}
private AsmSynthesisPath(ArrayDeque<String> signatures) {
this.signatures = signatures;
}
AsmSynthesisPath add(String signature) {
ArrayDeque<String> signatures = new ArrayDeque<>(this.signatures);
signatures.add(signature);
return new AsmSynthesisPath(signatures);
}
boolean has(String signature) {
return signatures.contains(signature);
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
boolean first = true;
for(String signature : signatures) {
if(first) {
first = false;
} else {
str.append(" < ");
}
str.append(signature);
}
return str.toString();
}
}
/**
* Capable of creating fragments from signatures by loading them or synthesizing them from other smaller fragments.
* <p>
* The synthesizer tries a lot of different combinations and keeps track of what has already been attempted.
*/
static class AsmFragmentTemplateSynthesizer {
/** Signature of the fragment being synthesized. */
private String creating;
/** The log. */
private CompileLog log;
AsmFragmentTemplateSynthesizer(String creating, CompileLog log) {
this.creating = creating;
this.log = log;
}
List<AsmFragmentTemplate> loadOrSynthesizeFragment(String signature, AsmSynthesisPath path) {
if(path.has(signature)) {
// Synthesis loop - stop it here
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Stopping synthesis loop at " + signature);
}
return new ArrayList<>();
}
// Add the current signature to the path
path = path.add(signature);
if(fragmentTemplateCache.get(signature) != null) {
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Using cached " + signature);
}
return fragmentTemplateCache.get(signature);
}
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Attempting " + signature);
}
List<AsmFragmentTemplate> candidates = new ArrayList<>();
// Synthesize the fragment from other fragments
List<AsmFragmentSynthesis> synths = getFragmentSyntheses();
for(AsmFragmentSynthesis synth : synths) {
List<AsmFragmentTemplate> synthesized = synth.synthesize(signature, path, this);
if(synthesized != null) {
if(log.isVerboseFragmentLog() && synthesized.size() > 0) {
log.append("Finding fragment " + path.toString() + " - Successfully synthesized " + synthesized.size() + " fragments ");
}
candidates.addAll(synthesized);
}
}
// Load the fragment from disk
CharStream fragmentCharStream = loadFragment(signature);
if(fragmentCharStream != null) {
try {
String body = fragmentCharStream.toString();
candidates.add(new AsmFragmentTemplate(signature, body));
} catch(StringIndexOutOfBoundsException e) {
throw new RuntimeException("Problem reading fragment file " + signature, e);
}
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Successfully loaded " + signature + ".asm");
}
}
if(candidates.size() == 0) {
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - No synthesis/file found!");
}
}
fragmentTemplateCache.put(signature, candidates);
return candidates;
}
public String getCreating() {
return creating;
}
public CompileLog getLog() {
return log;
}
}
public static class UnknownFragmentException extends RuntimeException {
private String fragmentSignature;
UnknownFragmentException(String signature) {
super("Fragment not found " + signature );
this.fragmentSignature = signature;
}
public String getFragmentSignature() {
return fragmentSignature;
}
}
}

View File

@ -19,7 +19,7 @@ public class AsmFragmentTemplate {
/** The parsed ASM lines. Initially null. Will be non-null, is the template is ever used to generate ASM code. */
private KickCParser.AsmLinesContext bodyAsm;
/** The synthesis that created the fragment. null if the fragment template was loaded. */
private AsmFragmentSynthesis synthesis;
private AsmFragmentTemplateSynthesisRule synthesis;
/** The sub fragment template that the synthesis modified to create this. null if the fragment template was loaded. */
private AsmFragmentTemplate subFragment;
@ -30,7 +30,7 @@ public class AsmFragmentTemplate {
this.file = true;
}
AsmFragmentTemplate(String signature, String body, AsmFragmentSynthesis synthesis, AsmFragmentTemplate subFragment) {
AsmFragmentTemplate(String signature, String body, AsmFragmentTemplateSynthesisRule synthesis, AsmFragmentTemplate subFragment) {
this.signature = signature;
this.body = body;
this.synthesis = synthesis;
@ -89,7 +89,7 @@ public class AsmFragmentTemplate {
return file;
}
public AsmFragmentSynthesis getSynthesis() {
public AsmFragmentTemplateSynthesisRule getSynthesis() {
return synthesis;
}

View File

@ -0,0 +1,570 @@
package dk.camelot64.kickc.fragment;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmProgram;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
/**
* Provides fragments from their signature.
* <p>
* The first priority is loading a fragment file from the fragment-folder.
* If no fragment file is found for the signature the manager attempts to synthesise a fragment from another fragment.
*/
public class AsmFragmentTemplateManager {
/** Cache for the best fragment templates. Maps signature to the best fragment template for the signature. */
private static Map<String, AsmFragmentTemplate> bestFragmentCache = new HashMap<>();
/** Caches all asm fragment templates for all encountered signatures. */
private static Map<String, List<AsmFragmentTemplate>> fragmentTemplateCache = new LinkedHashMap<>();
/** Special singleton representing that the fragment can not be synthesized or loaded. */
private static AsmFragmentTemplate UNKNOWN = new AsmFragmentTemplate("UNKNOWN", null);
/**
* All the synthesize rules available.
*/
private static List<AsmFragmentTemplateSynthesisRule> fragmentSyntheses;
static Map<String, List<AsmFragmentTemplate>> getFragmentTemplateCache() {
return fragmentTemplateCache;
}
public static AsmFragmentInstance getFragment(AsmFragmentInstanceSpec instanceSpec, CompileLog log) {
AsmFragmentTemplate bestTemplate = bestFragmentCache.get(instanceSpec.getSignature());
if(bestTemplate == UNKNOWN) {
if(log.isVerboseFragmentLog()) {
log.append("Unknown fragment " + instanceSpec.getSignature());
}
throw new UnknownFragmentException(instanceSpec);
}
if(bestTemplate == null) {
AsmFragmentTemplateSynthesizer synthesizer = new AsmFragmentTemplateSynthesizer(instanceSpec.getSignature(), log);
List<AsmFragmentTemplate> candidates = synthesizer.loadOrSynthesizeFragment(instanceSpec.getSignature(), new AsmSynthesisPath());
if(candidates.size() == 0) {
if(log.isVerboseFragmentLog()) {
log.append("Unknown fragment " + instanceSpec.getSignature());
}
bestFragmentCache.put(instanceSpec.getSignature(), UNKNOWN);
throw new UnknownFragmentException(instanceSpec);
}
double minScore = Double.MAX_VALUE;
double maxScore = Double.MIN_VALUE;
AsmFragmentTemplate maxTemplate = null;
for(AsmFragmentTemplate candidateTemplate : candidates) {
AsmFragmentInstance candidateFragment = new AsmFragmentInstance(
instanceSpec.getProgram(),
instanceSpec.getSignature(),
instanceSpec.getCodeScope(),
candidateTemplate,
instanceSpec.getBindings());
AsmProgram candidateAsm = new AsmProgram();
candidateAsm.startSegment(null, instanceSpec.toString());
candidateFragment.generate(candidateAsm);
double score = candidateAsm.getCycles();
if(score < minScore) {
minScore = score;
bestTemplate = candidateTemplate;
}
if(score > maxScore) {
maxScore = score;
maxTemplate = candidateTemplate;
}
}
if(log.isVerboseFragmentLog()) {
log.append("Found fragment " + bestTemplate.getName() + " score: " + minScore + " from " + candidates.size() + " candidates");
}
bestFragmentCache.put(instanceSpec.getSignature(), bestTemplate);
}
// Count usages
AsmFragmentTemplateUsages.incUsage(bestTemplate);
// Return the resulting fragment instance
return new AsmFragmentInstance(
instanceSpec.getProgram(),
instanceSpec.getSignature(),
instanceSpec.getCodeScope(),
bestTemplate,
instanceSpec.getBindings());
}
/**
* Look for a fragment on the disk.
*
* @param signature The fragment signature
* @return The fragment file contents. Null if the fragment is not on the disk.
*/
private static CharStream loadFragment(String signature) {
ClassLoader classLoader = AsmFragmentTemplateManager.class.getClassLoader();
URL fragmentUrl = classLoader.getResource("dk/camelot64/kickc/fragment/asm/" + signature + ".asm");
if(fragmentUrl == null) {
return null;
}
try {
InputStream fragmentStream = fragmentUrl.openStream();
return CharStreams.fromStream(fragmentStream);
} catch(IOException e) {
throw new RuntimeException("Error loading fragment file " + fragmentUrl);
}
}
static File[] allFragmentFiles() {
ClassLoader classLoader = AsmFragmentTemplateManager.class.getClassLoader();
String path = classLoader.getResource("dk/camelot64/kickc/fragment/asm/").getPath();
return new File(path).listFiles((dir, name) -> name.endsWith(".asm"));
}
private static List<AsmFragmentTemplateSynthesisRule> getFragmentSyntheses() {
if(fragmentSyntheses == null) {
fragmentSyntheses = initFragmentSyntheses();
}
return fragmentSyntheses;
}
private static List<AsmFragmentTemplateSynthesisRule> initFragmentSyntheses() {
Map<String, String> mapZ = new LinkedHashMap<>();
mapZ.put("z2", "z1");
mapZ.put("z3", "z2");
Map<String, String> mapZ2 = new LinkedHashMap<>();
mapZ2.put("z3", "z1");
Map<String, String> mapZ3 = new LinkedHashMap<>();
mapZ3.put("z3", "z2");
Map<String, String> mapC = new LinkedHashMap<>();
mapC.put("c2", "c1");
mapC.put("c3", "c2");
Map<String, String> mapC3 = new LinkedHashMap<>();
mapC3.put("c3", "c2");
Map<String, String> mapZC = new LinkedHashMap<>();
mapZC.putAll(mapZ);
mapZC.putAll(mapC);
Map<String, String> mapSToU = new LinkedHashMap<>();
mapSToU.put("vbsz1", "vbuz1");
mapSToU.put("vbsz2", "vbuz2");
mapSToU.put("vbsz3", "vbuz3");
mapSToU.put("vbsc1", "vbuc1");
mapSToU.put("vbsc2", "vbuc2");
mapSToU.put("vbsc3", "vbuc3");
mapSToU.put("vbsaa", "vbuaa");
mapSToU.put("vbsxx", "vbuxx");
mapSToU.put("vbsyy", "vbuyy");
mapSToU.put("vwsz1", "vwuz1");
mapSToU.put("vwsz2", "vwuz2");
mapSToU.put("vwsz3", "vwuz3");
mapSToU.put("vwsc1", "vwuc1");
mapSToU.put("vwsc2", "vwuc2");
mapSToU.put("vwsc3", "vwuc3");
List<AsmFragmentTemplateSynthesisRule> synths = new ArrayList<>();
// NEW STYLE REWRITES - Utilizes that all combinations are tried
// Replace first AA with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)aa(.*)", "...aa=.*|.*xx.*", "tax", "$1xx$2", null, null));
// Replace two AAs with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)aa(.*vb.)aa(.*)", "...aa=.*|.*xx.*", "tax", "$1xx$2xx$3", null, null));
// Replace second (not first) AA with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)aa(.*vb.)aa(.*)", "...aa=.*|.*xx.*", "tax", "$1aa$2xx$3", null, null));
// Replace first AA with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)aa(.*)", "...aa=.*|.*yy.*", "tay", "$1yy$2", null, null));
// Replace two AAs with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)aa(.*vb.)aa(.*)", "...aa=.*|.*yy.*", "tay", "$1yy$2yy$3", null, null));
// Replace second (not first) AA with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)aa(.*vb.)aa(.*)", "...aa=.*|.*yy.*", "tay", "$1aa$2yy$3", null, null));
// Replace first XX with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)xx(.*)", "...xx=.*|.*aa.*", "txa", "$1aa$2", null, null));
// Replace two XXs with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)xx(.*vb.)xx(.*)", "...xx=.*|.*aa.*", "txa", "$1aa$2aa$3", null, null));
// Replace second (not first) XX with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)xx(.*vb.)xx(.*)", "...xx=.*|.*aa.*", "txa", "$1xx$2aa$3", null, null));
// Replace first YY with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)yy(.*)", "...yy=.*|.*aa.*", "tya", "$1aa$2", null, null));
// Replace two YYs with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)yy(.*vb.)yy(.*)", "...yy=.*|.*aa.*", "tya", "$1aa$2aa$3", null, null));
// Replace second (not first) YY with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)yy(.*vb.)yy(.*)", "...yy=.*|.*aa.*", "tya", "$1yy$2aa$3", null, null));
// Replace Z1 with AA (only one)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*|.*aa.*", "lda {z1}", "$1aa$2", null, mapZ));
// Replace two Z1s with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*z1.*|.*aa.*", "lda {z1}", "$1aa$2aa$3", null, mapZ));
// Replace first (not second) Z1 with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*)z1(.*)", "...z1=.*|.*aa.*", "lda {z1}", "$1aa$2z1$3", null, null));
// Replace second (not first) Z1 with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z1(.*vb.)z1(.*)", "...z1=.*|.*aa.*", "lda {z1}", "$1z1$2aa$3", null, null));
// Replace Z1 with YY (only one)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*|.*yy.*", "ldy {z1}", "$1yy$2", null, mapZ));
// Replace two Z1s with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*z1.*|.*yy.*", "ldy {z1}", "$1yy$2yy$3", null, mapZ));
// Replace first (not second) Z1 with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*)z1(.*)", "...z1=.*|.*yy.*", "ldy {z1}", "$1yy$2z1$3", null, null));
// Replace second (not first) Z1 with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z1(.*vb.)z1(.*)", "...z1=.*|.*yy.*", "ldy {z1}", "$1z1$2yy$3", null, null));
// Replace Z1 with XX (only one)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*|.*xx.*", "ldx {z1}", "$1xx$2", null, mapZ));
// Replace two Z1s with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*vb.)z1(.*)", "...z1=.*|.*z1.*z1.*z1.*|.*xx.*", "ldx {z1}", "$1xx$2xx$3", null, mapZ));
// Replace first (not second) Z1 with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z1(.*)z1(.*)", "...z1=.*|.*xx.*", "ldx {z1}", "$1xx$2z1$3", null, null));
// Replace second (not first) Z1 with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z1(.*vb.)z1(.*)", "...z1=.*|.*xx.*", "ldx {z1}", "$1z1$2xx$3", null, null));
// Replace Z2 with AA (only one)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*|.*aa.*", "lda {z2}", "$1aa$2", null, mapZ3));
// Replace two Z2s with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*z2.*|.*aa.*", "lda {z2}", "$1aa$2aa$3", null, mapZ3));
// Replace first (of 2) Z2 with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*)z2(.*)", "...z2=.*|.*aa.*", "lda {z2}", "$1aa$2z2$3", null, null));
// Replace second (of 2) Z2 with AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z2(.*vb.)z2(.*)", "...z2=.*|.*aa.*", "lda {z2}", "$1z2$2aa$3", null, null));
// Replace Z2 with YY (only one)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*|.*yy.*", "ldy {z2}", "$1yy$2", null, mapZ3));
// Replace two Z2s with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*z2.*|.*yy.*", "ldy {z2}", "$1yy$2yy$3", null, mapZ3));
// Replace first (of 2) Z2 with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*)z2(.*)", "...z2=.*|.*yy.*", "ldy {z2}", "$1yy$2z2$3", null, null));
// Replace second (of 2) Z2 with YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z2(.*vb.)z2(.*)", "...z2=.*|.*yy.*", "ldy {z2}", "$1z2$2yy$3", null, null));
// Replace Z2 with XX(only one)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*|.*xx.*", "ldx {z2}", "$1xx$2", null, mapZ3));
// Replace two Z2s with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*vb.)z2(.*)", "...z2=.*|.*z2.*z2.*z2.*|.*xx.*", "ldx {z2}", "$1xx$2xx$3", null, mapZ3));
// Replace first (of 2) Z2 with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*vb.)z2(.*)z2(.*)", "...z2=.*|.*xx.*", "ldx {z2}", "$1xx$2z2$3", null, null));
// Replace second (of 2) Z2 with XX
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z2(.*vb.)z2(.*)", "...z2=.*|.*xx.*", "ldx {z2}", "$1z2$2xx$3", null, null));
// Rewrite comparisons < to >
//synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_gt_(.*)_then_(.*)", null, null, "$2_lt_$1_then_$3", null, null));
// Rewrite comparisons > to <
//synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_lt_(.*)_then_(.*)", null, null, "$2_gt_$1_then_$3", null, null));
// Rewrite comparisons <= to >=
//synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_le_(.*)_then_(.*)", null, null, "$2_ge_$1_then_$3", null, null));
// Rewrite comparisons >= to <=
//synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_ge_(.*)_then_(.*)", null, null, "$2_le_$1_then_$3", null, null));
// Rewrite comparisons swap ==
//synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_eq_(.*)_then_(.*)", null, null, "$2_eq_$1_then_$3", null, null));
// Rewrite comparisons swap !=
//synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_neq_(.*)_then_(.*)", null, null, "$2_neq_$1_then_$3", null, null));
// OLD STYLE REWRITES - written when only one rule could be taken
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(band|bor|bxor|plus)_(vb.aa)", ".*=vb.aa_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(band|bor|bxor|plus)_(vb.xx)", ".*=vb.[ax][ax]_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(band|bor|bxor|plus)_(vb.yy)", ".*=vb.[axy][axy]_.*", null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("vbuxx=(.*)", null, null, "vbuaa=$1", "tax\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("vbsxx=(.*)", null, null, "vbsaa=$1", "tax\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("vbuyy=(.*)", null, null, "vbuaa=$1", "tay\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("vbsyy=(.*)", null, null, "vbsaa=$1", "tay\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("vbuz1=(.*)", ".*=.*vb.z1.*", null, "vbuaa=$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("vbsz1=(.*)", ".*=.*vb.z1.*", null, "vbsaa=$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("_deref_pb(.)c1=(.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "sta {c1}\n", mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("_deref_pb(.)c1=(.*c1.*)", null, null, "vb$1aa=$2", "sta {c1}\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("_deref_pbuz1=(.*)", ".*z1.*z1.*", null, "vbuaa=$1", "ldy #0\n" + "sta ({z1}),y\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("_deref_pbuz1=(.*z1.*)", null, null, "vbuaa=$1", "ldy #0\n" + "sta ({z1}),y\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuz1=(.*)", ".*z1.*z1.*|.*c1.*c1.*", null, "vb$1aa=$2", "ldx {z1}\n" + "sta {c1},x\n", mapZC));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy=(.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "sta {c1},y\n", mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuxx=(.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "sta {c1},x\n", mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuz2=(.*)", ".*z1.*z1.*|.*z2.*z2.*", null, "vb$1aa=$2", "ldy {z2}\n" + "sta ({z1}),y\n", mapZ2));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=_deref_pb(.)c1(.*)", ".*=.*aa.*", "lda {c1}\n", "$1=vb$2aa$3", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=_deref_pb(.)z1(.*)", ".*z1.*z1.*|.*=.*aa.*|.*=.*yy.*", "ldy #0\n" + "lda ({z1}),y\n", "$1=vb$2aa$3", null, mapZ));
// Convert array indexing with A register to X/Y register by prefixing tax/tay (..._derefidx_vbuaa... -> ..._derefidx_vbuxx... /... _derefidx_vbuyy... )
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*xx.*", "tax\n", "$1=$2_derefidx_vbuxx$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*yy.*", "tay\n", "$1=$2_derefidx_vbuyy$3", null, null));
// Convert array indexing with zero page to x/y register by prefixing ldx z1 / ldy z1 ( ..._derefidx_vbuzn... -> ..._derefidx_vbuxx... / ..._derefidx_vbuyy... )
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*xx.*|.*z1.*z1.*", "ldx {z1}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*yy.*|.*z1.*z1.*", "ldy {z1}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*xx.*|.*z2.*z2.*", "ldx {z2}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ3));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*yy.*|.*z2.*z2.*", "ldy {z2}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ3));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*yy.*", "ldy {z3}\n", "$1=$2_derefidx_vbuyy$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*xx.*", "ldx {z3}\n", "$1=$2_derefidx_vbuxx$3", null, null));
// Convert array indexing twice with A/zp1/zp2 to X/Y register with a ldx/ldy prefix ( ..._derefidx_vbunn..._derefidx_vbunn... -> ..._derefidx_vbuxx..._derefidx_vbuxx... )
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuaa(.*)_derefidx_vbuaa(.*)", ".*aa.*aa.*aa.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "tax\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuaa(.*)_derefidx_vbuaa(.*)", ".*aa.*aa.*aa.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "tay\n", null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z1}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z1}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z2}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z2}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuz1=(.*c1.*)", ".*z1.*z1.*", null, "vb$1aa=$2", "ldx {z1}\n" + "sta {c1},x\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuz1=(.*z1.*)", ".*c1.*c1.*", null, "vb$1aa=$2", "ldx {z1}\n" + "sta {c1},x\n", mapC));
// Convert X/Y-based array indexing of a constant pointer into A-register by prefixing lda cn,x / lda cn,y ( ...pb.c1_derefidx_vbuxx... / ...pb.c1_derefidx_vbuyy... -> ...vb.aa... )
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*c1.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*c1.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*c2.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*c2.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
// Convert zeropage/constants/X/Y in assignments to A-register using LDA/TXA/TYA prefix
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuz1(.*)", ".*z1.*=.*|.*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2vbuaa$3", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsz1(.*)", ".*z1.*=.*|.*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2vbsaa$3", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuz2(.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbuaa$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsz2(.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbsaa$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuz2(.*z3.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbuaa$3", null, mapZ3));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsz2(.*z3.*)", ".*z2.*=.*|.*=.*aa.*|.*z2.*z2.*|.*z3.*", "lda {z2}\n", "$1=$2vbsaa$3", null, mapZ3));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbuxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbsxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbsaa", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbuyy", ".*=.*[ay][ay].*yy|.*derefidx_vb.yy", "tya\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbsyy", ".*=-*[ay][ay].*yy|.*derefidx_vb.yy", "tya\n", "$1=$2_vbsaa", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbuz1", ".*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2_vbuaa", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbsz1", ".*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2_vbsaa", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbuz2", ".*=.*aa.*|.*z2.*z2.*", "lda {z2}\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_vbuz3", ".*=.*aa.*|.*z3.*z3.*", "lda {z3}\n", "$1=$2_vbuaa", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("vbuz1=vbuz1(.*)", ".*=.*vb.aa.*|.*z1.*z1.*z1.*", "lda {z1}\n", "vbuaa=vbuaa$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("vbsz1=vbsz1(.*)", ".*=.*vb.aa.*|.*z1.*z1.*z1.*", "lda {z1}\n", "vbsaa=vbsaa$1", "sta {z1}\n", mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("vbuz1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*|.*z1.*z1.*", "lda {z1}\n", "vbuaa_$1_$2", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("vbsz1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*|.*z1.*z1.*", "lda {z1}\n", "vbsaa_$1_$2", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("_deref_pb(.)c1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*", "lda {c1}\n", "vb$1aa_$2_$3", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("_deref_pb(.)z1_(lt|gt|le|ge|eq|neq)_(.*)", ".*vb.aa.*|.*vb.yy.*|.*z1.*z1.*", "ldy #0\n" + "lda ({z1}),y\n", "vb$1aa_$2_$3", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1_(.*)", ".*z1.*z1.*|.*.yy.*", "ldy {z1}\n", "$1_derefidx_vbuyy_$2", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1_(lt|gt|le|ge|eq|neq)_(.*)", ".*z1.*z1.*|.*vb.xx.*", "ldx {z1}\n", "$1_derefidx_vbuxx_$2_$3", null, mapZ));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy_(lt|gt|le|ge|eq|neq)_(.*)", ".*c1.*c1.*|.*aa.*", "lda {c1},y\n", "vb$1aa_$2_$3", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy_(lt|gt|le|ge|eq|neq)_(.*c1.*)", ".*aa.*", "lda {c1},y\n", "vb$1aa_$2_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuxx_(lt|gt|le|ge|eq|neq)_(.*)", ".*c1.*c1.*|.*aa.*", "lda {c1},x\n", "vb$1aa_$2_$3", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuxx_(lt|gt|le|ge|eq|neq)_(.*c1.*)", ".*aa.*", "lda {c1},x\n", "vb$1aa_$2_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_ge_(vb.aa)_then_(.*)", ".*vb.aa.*_ge.*", null, "$2_le_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_ge_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_ge.*", null, "$2_le_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_ge_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_ge.*", null, "$2_le_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_lt_(vb.aa)_then_(.*)", ".*vb.aa.*_lt.*", null, "$2_gt_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_lt_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_lt.*", null, "$2_gt_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_lt_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_lt.*", null, "$2_gt_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_gt_(vb.aa)_then_(.*)", ".*vb.aa.*_gt.*", null, "$2_lt_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_gt_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_gt.*", null, "$2_lt_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_gt_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_gt.*", null, "$2_lt_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_le_(vb.aa)_then_(.*)", ".*vb.aa.*_le.*", null, "$2_ge_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_le_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_le.*", null, "$2_ge_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_le_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_le.*", null, "$2_ge_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_neq_(vb.aa)_then_(.*)", ".*vb.aa.*_neq.*", null, "$2_neq_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_neq_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_neq.*", null, "$2_neq_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_neq_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_neq.*", null, "$2_neq_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_eq_(vb.aa)_then_(.*)", ".*vb.aa.*_eq.*", null, "$2_eq_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_eq_(vb.xx)_then_(.*)", ".*vb.[ax][ax].*_eq.*", null, "$2_eq_$1_then_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_eq_(vb.yy)_then_(.*)", ".*vb.[axy][axy].*_eq.*", null, "$2_eq_$1_then_$3", null, null));
// Use unsigned ASM to synthesize signed ASM ( ...vbs... -> ...vbu... )
synths.add(new AsmFragmentTemplateSynthesisRule("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_(eq|neq)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_then_(.*)", null, null, "$1_$2_$3_then_$4", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_(plus|band|bxor|bor)_(vbsz.|csoby.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2_$3_$4", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)=_(inc|dec)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=_$2_$3", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(vwsz.|vwsc.)_(eq|neq)_(vwsz.|vwsc.)_then_(.*)", null, null, "$1_$2_$3_then_$4", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(vwsz.)=(vwsz.|vwsc.)", null, null, "$1=$2", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(v.sz.)=(v.s..)_(band|bxor|bor)_(v.s..)", null, null, "$1=$2_$3_$4", null, mapSToU));
synths.add(new AsmFragmentTemplateSynthesisRule("(vbuz.|vbuaa|vbuxx|vbuyy)=_(lo|hi)_vws(z.|c.)", null, null, "$1=_$2_vwu$3", null, mapSToU));
// Use constant word ASM to synthesize unsigned constant byte ASM ( ...vb.c... -> vw.c... )
synths.add(new AsmFragmentTemplateSynthesisRule("(vwuz.)=(vwuz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwuc$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(vwuz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwuz.)", null, null, "$1=vwuc$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(vwsz.)=(vwsz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwsc$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(vwsz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwsz.)", null, null, "$1=vwsc$2_$3_$4", null, null));
// Move constant words to the end of the ASM signature for symmetric operators ( ...vw.c...vw.z... -> ...vw.z...vw.c... )
synths.add(new AsmFragmentTemplateSynthesisRule("(vwuz.)=(vwuc.)_(plus|band|bxor|bor)_(vwuz.)", null, null, "$1=$4_$3_$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(vwsz.)=(vwsc.)_(plus|band|bxor|bor)_(vwsz.)", null, null, "$1=$4_$3_$2", null, null));
// Use Z1/Z2 ASM to synthesize Z1-only code ( ...z1...z1... -> ...z1...z2... )
synths.add(new AsmFragmentTemplateSynthesisRule("(v..)z1=(v..)z1_(plus|minus|band|bxor|bor)_(.*)", ".*z2.*", null, "$1z1=$2z2_$3_$4", null, mapZ, false));
synths.add(new AsmFragmentTemplateSynthesisRule("(v..)z1=(.*)_(plus|minus|band|bxor|bor)_(v..)z1", ".*z2.*", null, "$1z1=$2_$3_$4z2", null, mapZ, false));
synths.add(new AsmFragmentTemplateSynthesisRule("(v..)z1=_(neg|lo|hi)_(v..)z1", ".*z2.*", null, "$1z1=_$2_$3z2", null, mapZ, false));
// Convert INC/DEC to +1/-1 ( ..._inc_xxx... -> ...xxx_plus_1_... / ..._dec_xxx... -> ...xxx_minus_1_... )
synths.add(new AsmFragmentTemplateSynthesisRule("vb(.)aa=_inc_(.*)", null, null, "vb$1aa=$2_plus_1", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("vb(.)aa=_dec_(.*)", null, null, "vb$1aa=$2_minus_1", null, null));
// Synthesize XX/YY using AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuxx(.*)", ".*=.*aa.*|.*derefidx_vb.xx.*", "txa\n", "$1=$2vbuaa$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsxx(.*)", ".*=.*aa.*|.*derefidx_vb.xx.*", "txa\n", "$1=$2vbsaa$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuyy(.*)", ".*=.*aa.*|.*derefidx_vb.yy.*", "tya\n", "$1=$2vbuaa$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsyy(.*)", ".*=.*aa.*|.*derefidx_vb.yy.*", "tya\n", "$1=$2vbsaa$3", null, null));
// Synthesize constants using AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuc1(.*)", ".*=.*aa.*|.*c1.*c1.*|.*c1_deref.*", "lda #{c1}\n", "$1=$2vbuaa$3", null, mapC));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsc1(.*)", ".*=.*aa.*|.*c1.*c1.*|.*c1_deref.*", "lda #{c1}\n", "$1=$2vbsaa$3", null, mapC));
// Synthesize some constant pointers as constant words
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_(lt|gt|le|ge|eq|neq)_p..([cz].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)_(lt|gt|le|ge|eq|neq)_(.*)", null, null, "vwu$1_$2_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([zc].)", null, null, "$1=vwu$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(plus|minus|bor|bxor)_p..([cz].)", null, null, "$1=$2_$3_vwu$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(plus|minus|bor|bxor)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwu$1=$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
return synths;
}
/**
* The synthesis path describes the different signatures being attempted to synthesize a fragment.
* Used to avoid infinite loops during synthesis.
*/
static class AsmSynthesisPath {
private ArrayDeque<String> signatures;
public AsmSynthesisPath() {
this.signatures = new ArrayDeque<>();
}
private AsmSynthesisPath(ArrayDeque<String> signatures) {
this.signatures = signatures;
}
AsmSynthesisPath add(String signature) {
ArrayDeque<String> signatures = new ArrayDeque<>(this.signatures);
signatures.add(signature);
return new AsmSynthesisPath(signatures);
}
boolean has(String signature) {
return signatures.contains(signature);
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
boolean first = true;
for(String signature : signatures) {
if(first) {
first = false;
} else {
str.append(" < ");
}
str.append(signature);
}
return str.toString();
}
}
/**
* Capable of creating fragments from signatures by loading them or synthesizing them from other smaller fragments.
* <p>
* The synthesizer tries a lot of different combinations and keeps track of what has already been attempted.
*/
static class AsmFragmentTemplateSynthesizer {
/** Signature of the fragment being synthesized. */
private String creating;
/** The log. */
private CompileLog log;
AsmFragmentTemplateSynthesizer(String creating, CompileLog log) {
this.creating = creating;
this.log = log;
}
List<AsmFragmentTemplate> loadOrSynthesizeFragment(String signature, AsmSynthesisPath path) {
if(path.has(signature)) {
// Synthesis loop - stop it here
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Stopping synthesis loop at " + signature);
}
return new ArrayList<>();
}
// Add the current signature to the path
path = path.add(signature);
if(fragmentTemplateCache.get(signature) != null) {
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Using cached " + signature);
}
return fragmentTemplateCache.get(signature);
}
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Attempting " + signature);
}
List<AsmFragmentTemplate> candidates = new ArrayList<>();
// Synthesize the fragment from other fragments
List<AsmFragmentTemplateSynthesisRule> synths = getFragmentSyntheses();
for(AsmFragmentTemplateSynthesisRule synth : synths) {
List<AsmFragmentTemplate> synthesized = synth.synthesize(signature, path, this);
if(synthesized != null) {
if(log.isVerboseFragmentLog() && synthesized.size() > 0) {
log.append("Finding fragment " + path.toString() + " - Successfully synthesized " + synthesized.size() + " fragments ");
}
candidates.addAll(synthesized);
}
}
// Load the fragment from disk
CharStream fragmentCharStream = loadFragment(signature);
if(fragmentCharStream != null) {
try {
String body = fragmentCharStream.toString();
candidates.add(new AsmFragmentTemplate(signature, body));
} catch(StringIndexOutOfBoundsException e) {
throw new RuntimeException("Problem reading fragment file " + signature, e);
}
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - Successfully loaded " + signature + ".asm");
}
}
if(candidates.size() == 0) {
if(log.isVerboseFragmentLog()) {
log.append("Finding fragment " + path.toString() + " - No synthesis/file found!");
}
}
fragmentTemplateCache.put(signature, candidates);
return candidates;
}
public String getCreating() {
return creating;
}
public CompileLog getLog() {
return log;
}
}
public static class UnknownFragmentException extends RuntimeException {
private AsmFragmentInstanceSpec fragmentInstanceSpec;
UnknownFragmentException(AsmFragmentInstanceSpec fragmentInstanceSpec) {
super("Fragment not found " + fragmentInstanceSpec.getSignature() );
this.fragmentInstanceSpec = fragmentInstanceSpec;
}
public String getFragmentSignature() {
return fragmentInstanceSpec.getSignature();
}
public String getFragmentDescription() {
return fragmentInstanceSpec.toString();
}
public AsmFragmentInstanceSpec getFragmentInstanceSpec() {
return fragmentInstanceSpec;
}
}
}

View File

@ -8,7 +8,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** AsmFragment synthesis mechanism based on matching fragment signature and reusing another fragment with added prefix/postfix and some bind-mappings */
class AsmFragmentSynthesis {
class AsmFragmentTemplateSynthesisRule {
private String sigMatch;
private String sigAvoid;
@ -19,7 +19,7 @@ class AsmFragmentSynthesis {
private boolean mapSignature;
private String subSignature;
AsmFragmentSynthesis(String sigMatch, String sigAvoid, String asmPrefix, String sigReplace, String asmPostfix, Map<String, String> bindMappings, boolean mapSignature) {
AsmFragmentTemplateSynthesisRule(String sigMatch, String sigAvoid, String asmPrefix, String sigReplace, String asmPostfix, Map<String, String> bindMappings, boolean mapSignature) {
this.sigMatch = sigMatch;
this.sigAvoid = sigAvoid;
this.asmPrefix = asmPrefix;
@ -29,7 +29,7 @@ class AsmFragmentSynthesis {
this.mapSignature = mapSignature;
}
public AsmFragmentSynthesis(String sigMatch, String sigAvoid, String asmPrefix, String sigReplace, String asmPostfix, Map<String, String> bindMappings) {
public AsmFragmentTemplateSynthesisRule(String sigMatch, String sigAvoid, String asmPrefix, String sigReplace, String asmPostfix, Map<String, String> bindMappings) {
this(sigMatch, sigAvoid, asmPrefix, sigReplace, asmPostfix, bindMappings, true);
}
@ -48,7 +48,7 @@ class AsmFragmentSynthesis {
return sigMatch + (sigAvoid == null ? "" : ("/" + sigAvoid));
}
public List<AsmFragmentTemplate> synthesize(String signature, AsmFragmentManager.AsmSynthesisPath path, AsmFragmentManager.AsmFragmentTemplateSynthesizer synthesizer) {
public List<AsmFragmentTemplate> synthesize(String signature, AsmFragmentTemplateManager.AsmSynthesisPath path, AsmFragmentTemplateManager.AsmFragmentTemplateSynthesizer synthesizer) {
ArrayList<AsmFragmentTemplate> candidates = new ArrayList<>();
if(signature.matches(sigMatch)) {
if(sigAvoid == null || !signature.matches(sigAvoid)) {

View File

@ -5,8 +5,8 @@ import dk.camelot64.kickc.CompileLog;
import java.io.File;
import java.util.*;
/** Statistics for usage of the ASM fragments. Also contains a methos for identifying redundant/unused files. */
public class AsmFragmentUsages {
/** Statistics for usage of the ASM fragments. Also contains a methods for identifying redundant/unused files. */
public class AsmFragmentTemplateUsages {
/** Usage Statistics for fragment templates. */
private static Map<AsmFragmentTemplate, Integer> fragmentTemplateUsage = new HashMap<>();
@ -35,10 +35,10 @@ public class AsmFragmentUsages {
*/
public static void logUsages(CompileLog log, boolean logRedundantFiles, boolean logUnusedFiles, boolean logFileDetails, boolean logAllDetails) {
Map<String, List<AsmFragmentTemplate>> fragmentTemplateCache = AsmFragmentManager.getFragmentTemplateCache();
Map<String, List<AsmFragmentTemplate>> fragmentTemplateCache = AsmFragmentTemplateManager.getFragmentTemplateCache();
ArrayList<String> signatures = new ArrayList<>(fragmentTemplateCache.keySet());
Collections.sort(signatures);
File[] files = AsmFragmentManager.allFragmentFiles();
File[] files = AsmFragmentTemplateManager.allFragmentFiles();
if(logRedundantFiles) {
// Find all file fragments that were bested by a synthesized fragment
@ -71,8 +71,8 @@ public class AsmFragmentUsages {
String fileName = file.getName();
String signature = fileName.substring(0, fileName.length() - 4);
// Try to synthesize the fragment - and check if the synthesis is as good as the file body
AsmFragmentManager.AsmFragmentTemplateSynthesizer synthesizer = new AsmFragmentManager.AsmFragmentTemplateSynthesizer(signature, log);
List<AsmFragmentTemplate> templates = synthesizer.loadOrSynthesizeFragment(signature, new AsmFragmentManager.AsmSynthesisPath());
AsmFragmentTemplateManager.AsmFragmentTemplateSynthesizer synthesizer = new AsmFragmentTemplateManager.AsmFragmentTemplateSynthesizer(signature, log);
List<AsmFragmentTemplate> templates = synthesizer.loadOrSynthesizeFragment(signature, new AsmFragmentTemplateManager.AsmSynthesisPath());
AsmFragmentTemplate fileTemplate = null;
for(AsmFragmentTemplate template : templates) {
if(template.isFile()) {

View File

@ -217,13 +217,13 @@ public class Pass4CodeGeneration {
if(aluState.hasAluAssignment()) {
StatementAssignment assignmentAlu = aluState.getAluAssignment();
if(!(statement instanceof StatementAssignment)) {
throw new AsmFragment.AluNotApplicableException();
throw new AsmFragmentInstance.AluNotApplicableException();
}
StatementAssignment assignment = (StatementAssignment) statement;
AsmFragmentSignature signature = new AsmFragmentSignature(assignment, assignmentAlu, program);
AsmFragment asmFragment = AsmFragmentManager.getFragment(signature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragment.getFragmentName());
asmFragment.generate(asm);
AsmFragmentInstanceSpec signature = new AsmFragmentInstanceSpec(assignment, assignmentAlu, program);
AsmFragmentInstance asmFragmentInstance = AsmFragmentTemplateManager.getFragment(signature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragmentInstance.getFragmentName());
asmFragmentInstance.generate(asm);
aluState.clear();
return;
}
@ -247,17 +247,17 @@ public class Pass4CodeGeneration {
if(assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) {
asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue));
} else {
AsmFragmentSignature asmFragmentSignature = new AsmFragmentSignature(assignment, program);
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmFragmentSignature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragment.getFragmentName());
asmFragment.generate(asm);
AsmFragmentInstanceSpec asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(assignment, program);
AsmFragmentInstance asmFragmentInstance = AsmFragmentTemplateManager.getFragment(asmFragmentInstanceSpec, program.getLog());
asm.getCurrentSegment().setFragment(asmFragmentInstance.getFragmentName());
asmFragmentInstance.generate(asm);
}
}
} else if(statement instanceof StatementConditionalJump) {
AsmFragmentSignature asmSignature = new AsmFragmentSignature((StatementConditionalJump) statement, block, program, getGraph());
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmSignature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragment.getFragmentName());
asmFragment.generate(asm);
AsmFragmentInstanceSpec asmSignature = new AsmFragmentInstanceSpec((StatementConditionalJump) statement, block, program, getGraph());
AsmFragmentInstance asmFragmentInstance = AsmFragmentTemplateManager.getFragment(asmSignature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragmentInstance.getFragmentName());
asmFragmentInstance.generate(asm);
} else if(statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
if(genCallPhiEntry) {
@ -276,8 +276,8 @@ public class Pass4CodeGeneration {
} else if(statement instanceof StatementAsm) {
StatementAsm statementAsm = (StatementAsm) statement;
HashMap<String, Value> bindings = new HashMap<>();
AsmFragment asmFragment = new AsmFragment(program, "inline", block.getScope(), new AsmFragmentTemplate(statementAsm.getAsmLines()), bindings);
asmFragment.generate(asm);
AsmFragmentInstance asmFragmentInstance = new AsmFragmentInstance(program, "inline", block.getScope(), new AsmFragmentTemplate(statementAsm.getAsmLines()), bindings);
asmFragmentInstance.generate(asm);
} else {
throw new RuntimeException("Statement not supported " + statement);
}
@ -340,10 +340,10 @@ public class Pass4CodeGeneration {
if(isRegisterCopy(lValue, rValue)) {
asm.getCurrentSegment().setFragment("register_copy");
} else {
AsmFragmentSignature asmSignature = new AsmFragmentSignature(lValue, rValue, program, scope);
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmSignature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragment.getFragmentName());
asmFragment.generate(asm);
AsmFragmentInstanceSpec asmSignature = new AsmFragmentInstanceSpec(lValue, rValue, program, scope);
AsmFragmentInstance asmFragmentInstance = AsmFragmentTemplateManager.getFragment(asmSignature, program.getLog());
asm.getCurrentSegment().setFragment(asmFragmentInstance.getFragmentName());
asmFragmentInstance.generate(asm);
}
}
transition.setGenerated(true);

View File

@ -2,8 +2,9 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.asm.AsmSegment;
import dk.camelot64.kickc.fragment.AsmFragment;
import dk.camelot64.kickc.fragment.AsmFragmentManager;
import dk.camelot64.kickc.fragment.AsmFragmentInstance;
import dk.camelot64.kickc.fragment.AsmFragmentInstanceSpec;
import dk.camelot64.kickc.fragment.AsmFragmentTemplateManager;
import dk.camelot64.kickc.model.*;
import java.util.*;
@ -27,7 +28,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
*/
static void chooseBestUpliftCombination(
RegisterCombinationIterator combinationIterator, int maxCombinations,
Set<String> unknownFragments,
Set<AsmFragmentInstanceSpec> unknownFragments,
ScopeRef scope,
Program program
) {
@ -85,7 +86,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
public static boolean generateCombinationAsm(
RegisterCombination combination,
Program program,
Set<String> unknownFragments,
Set<AsmFragmentInstanceSpec> unknownFragments,
ScopeRef scope) {
// Reset register allocation to original zero page allocation
new Pass4RegistersFinalize(program).allocate(false);
@ -106,8 +107,8 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
// Generate ASM
try {
new Pass4CodeGeneration(program, false).generate();
} catch(AsmFragmentManager.UnknownFragmentException e) {
unknownFragments.add(e.getFragmentSignature());
} catch(AsmFragmentTemplateManager.UnknownFragmentException e) {
unknownFragments.add(e.getFragmentInstanceSpec());
if(program.getLog().isVerboseUplift()) {
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + (scope == null ? "" : scope) + "] ");
@ -116,7 +117,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
program.getLog().append(msg.toString());
}
return false;
} catch(AsmFragment.AluNotApplicableException e) {
} catch(AsmFragmentInstance.AluNotApplicableException e) {
if(program.getLog().isVerboseUplift()) {
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + (scope == null ? "" : scope) + "] ");
@ -234,7 +235,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
public void performUplift(int maxCombinations) {
// Test uplift combinations to find the best one.
Set<String> unknownFragments = new LinkedHashSet<>();
Set<AsmFragmentInstanceSpec> unknownFragments = new LinkedHashSet<>();
List<RegisterUpliftScope> registerUpliftScopes = getProgram().getRegisterUpliftProgram().getRegisterUpliftScopes();
for(RegisterUpliftScope upliftScope : registerUpliftScopes) {
RegisterCombinationIterator combinationIterator = upliftScope.getCombinationIterator(getProgram().getRegisterPotentials());
@ -248,8 +249,8 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
if(unknownFragments.size() > 0) {
getLog().append("MISSING FRAGMENTS");
for(String unknownFragment : unknownFragments) {
getLog().append(" " + unknownFragment);
for(AsmFragmentInstanceSpec unknownFragment : unknownFragments) {
getLog().append(" " + unknownFragment.toString());
}
}
}

View File

@ -2,8 +2,8 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmClobber;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.fragment.AsmFragment;
import dk.camelot64.kickc.fragment.AsmFragmentManager;
import dk.camelot64.kickc.fragment.AsmFragmentInstance;
import dk.camelot64.kickc.fragment.AsmFragmentTemplateManager;
import dk.camelot64.kickc.model.*;
import java.util.*;
@ -196,15 +196,15 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
Pass4CodeGeneration.AsmCodegenAluState aluState = new Pass4CodeGeneration.AsmCodegenAluState();
try {
(new Pass4CodeGeneration(getProgram(), false)).generateStatementAsm(asm, block, statement, aluState, false);
} catch(AsmFragmentManager.UnknownFragmentException e) {
unknownFragments.add(e.getFragmentSignature());
} catch(AsmFragmentTemplateManager.UnknownFragmentException e) {
unknownFragments.add(e.getFragmentDescription());
StringBuilder msg = new StringBuilder();
msg.append("Potential register analysis " + statement);
msg.append(" missing fragment " + e.getFragmentSignature());
msg.append(" allocation: ").append(combination.toString());
getLog().append(msg.toString());
continue;
} catch(AsmFragment.AluNotApplicableException e) {
} catch(AsmFragmentInstance.AluNotApplicableException e) {
if(getProgram().getLog().isVerboseUplift()) {
StringBuilder msg = new StringBuilder();
msg.append("Potential register analysis ");

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.fragment.AsmFragmentInstanceSpec;
import dk.camelot64.kickc.model.*;
import java.util.*;
@ -23,7 +24,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
}
});
Set<String> unknownFragments = new LinkedHashSet<>();
Set<AsmFragmentInstanceSpec> unknownFragments = new LinkedHashSet<>();
for(LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
if(equivalenceClass.getRegister().getType().equals(Registers.RegisterType.ZP_BYTE)) {
@ -37,8 +38,8 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
if(unknownFragments.size() > 0) {
getLog().append("MISSING FRAGMENTS");
for(String unknownFragment : unknownFragments) {
getLog().append(" " + unknownFragment);
for(AsmFragmentInstanceSpec unknownFragment : unknownFragments) {
getLog().append(" " + unknownFragment.toString());
}
}

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.fragment.AsmFragmentInstanceSpec;
import dk.camelot64.kickc.model.*;
import java.util.HashSet;
@ -87,7 +88,7 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
boolean success = Pass4RegisterUpliftCombinations.generateCombinationAsm(
combination,
getProgram(),
new HashSet<String>(),
new HashSet<>(),
null);
if(success) {

View File

@ -2,7 +2,7 @@ package dk.camelot64.kickc.test;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.Compiler;
import dk.camelot64.kickc.fragment.AsmFragmentUsages;
import dk.camelot64.kickc.fragment.AsmFragmentTemplateUsages;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import org.junit.AfterClass;
@ -32,7 +32,7 @@ public class TestPrograms {
public static void tearDown() throws Exception {
CompileLog log = new CompileLog();
log.setSysOut(true);
AsmFragmentUsages.logUsages(log, false, false, false, false);
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false);
}
@Test

View File

@ -500,8 +500,12 @@ Uplift Scope [main]
Uplifting [line] best 426 combination reg byte x [ line::x#2 line::x#0 line::x#1 ] zp ZP_BYTE:2 [ line::x1#3 ]
Uplifting [] best 426 combination zp ZP_WORD:4 [ screen#10 screen#14 screen#11 ]
Uplifting [main] best 426 combination
MISSING FRAGMENTS
vbuxx_lt_vbuaa_then_la1(line:: vbuxx=(byte) line::x#1 vbuaa=(byte) line::x1#3 la1=(label) line::b1_from_b1 )
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ line::x1#3 ]
Uplifting [line] best 426 combination zp ZP_BYTE:2 [ line::x1#3 ]
MISSING FRAGMENTS
vbuxx_lt_vbuaa_then_la1(line:: vbuxx=(byte) line::x#1 vbuaa=(byte) line::x1#3 la1=(label) line::b1_from_b1 )
Allocated (was zp ZP_WORD:4) zp ZP_WORD:3 [ screen#10 screen#14 screen#11 ]
ASSEMBLER BEFORE OPTIMIZATION

View File

@ -447,8 +447,8 @@ main: {
}
REGISTER UPLIFT POTENTIAL REGISTERS
Potential register analysis [7] main::w#0 ← *(main::his#0 + main::h#4) w= main::l#2 missing fragment vwuz1=pbuc1_derefidx_vbuaa_word_vbuxx(main:: vwuz1=(word) main::w#0 pbuc1=(const byte[]) main::his#0 vbuaa=(byte) main::h#4 vbuxx=(byte) main::l#2 ) allocation: reg byte a [ main::h#4 main::h#1 ] reg byte x [ main::l#2 main::l#1 ] zp ZP_WORD:4 [ main::w#0 ]
Potential register analysis [7] main::w#0 ← *(main::his#0 + main::h#4) w= main::l#2 missing fragment vwuz1=pbuc1_derefidx_vbuaa_word_vbuyy(main:: vwuz1=(word) main::w#0 pbuc1=(const byte[]) main::his#0 vbuaa=(byte) main::h#4 vbuyy=(byte) main::l#2 ) allocation: reg byte a [ main::h#4 main::h#1 ] reg byte y [ main::l#2 main::l#1 ] zp ZP_WORD:4 [ main::w#0 ]
Potential register analysis [7] main::w#0 ← *(main::his#0 + main::h#4) w= main::l#2 missing fragment vwuz1=pbuc1_derefidx_vbuaa_word_vbuxx allocation: reg byte a [ main::h#4 main::h#1 ] reg byte x [ main::l#2 main::l#1 ] zp ZP_WORD:4 [ main::w#0 ]
Potential register analysis [7] main::w#0 ← *(main::his#0 + main::h#4) w= main::l#2 missing fragment vwuz1=pbuc1_derefidx_vbuaa_word_vbuyy allocation: reg byte a [ main::h#4 main::h#1 ] reg byte y [ main::l#2 main::l#1 ] zp ZP_WORD:4 [ main::w#0 ]
MISSING FRAGMENTS
vwuz1=pbuc1_derefidx_vbuaa_word_vbuxx(main:: vwuz1=(word) main::w#0 pbuc1=(const byte[]) main::his#0 vbuaa=(byte) main::h#4 vbuxx=(byte) main::l#2 )
vwuz1=pbuc1_derefidx_vbuaa_word_vbuyy(main:: vwuz1=(word) main::w#0 pbuc1=(const byte[]) main::his#0 vbuaa=(byte) main::h#4 vbuyy=(byte) main::l#2 )

View File

@ -3050,8 +3050,8 @@ Statement [7] if(*((const byte*) RASTER#0)!=(byte/word/signed word) 254) goto ma
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ scroll#18 scroll#10 scroll#3 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ current_bit#29 current_bit#12 current_bit#21 current_bit#5 ]
Statement [8] if(*((const byte*) RASTER#0)!=(byte/word/signed word) 255) goto main::@3 [ scroll#18 current_bit#29 nxt#31 current_chargen#27 ] ( main:2 [ scroll#18 current_bit#29 nxt#31 current_chargen#27 ] ) always clobbers reg byte a
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuxx(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuxx=(byte~) scroll_bit::$3 ) allocation: reg byte x [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuyy(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuyy=(byte~) scroll_bit::$3 ) allocation: reg byte y [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuxx=(byte~) scroll_bit::$3 )
vwuz1=_word_vbuyy(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuyy=(byte~) scroll_bit::$3 )
@ -3081,8 +3081,8 @@ Statement [68] *((byte*) fillscreen::cursor#2) ← (const byte) fillscreen::fill
Statement [70] if((byte*) fillscreen::cursor#1<(const byte*) SCREEN#0+(word/signed word) 1000) goto fillscreen::@1 [ fillscreen::cursor#1 ] ( main:2::fillscreen:5 [ fillscreen::cursor#1 ] ) always clobbers reg byte a
Statement [7] if(*((const byte*) RASTER#0)!=(byte/word/signed word) 254) goto main::@2 [ scroll#18 current_bit#29 nxt#31 current_chargen#27 ] ( main:2 [ scroll#18 current_bit#29 nxt#31 current_chargen#27 ] ) always clobbers reg byte a
Statement [8] if(*((const byte*) RASTER#0)!=(byte/word/signed word) 255) goto main::@3 [ scroll#18 current_bit#29 nxt#31 current_chargen#27 ] ( main:2 [ scroll#18 current_bit#29 nxt#31 current_chargen#27 ] ) always clobbers reg byte a
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuxx(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuxx=(byte~) scroll_bit::$3 ) allocation: reg byte x [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuyy(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuyy=(byte~) scroll_bit::$3 ) allocation: reg byte y [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
Potential register analysis [27] scroll_bit::c#0 ← ((word)) scroll_bit::$3 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ scroll_bit::$3 ] zp ZP_WORD:18 [ scroll_bit::c#0 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuxx=(byte~) scroll_bit::$3 )
vwuz1=_word_vbuyy(scroll_bit:: vwuz1=(word) scroll_bit::c#0 vbuyy=(byte~) scroll_bit::$3 )

View File

@ -354,16 +354,16 @@ main: {
}
REGISTER UPLIFT POTENTIAL REGISTERS
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsxx_lt_vbuc1_then_la1(main:: vbsxx=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 ) allocation: reg byte x [ main::i#2 main::i#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsyy_lt_vbuc1_then_la1(main:: vbsyy=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 ) allocation: reg byte y [ main::i#2 main::i#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsxx_lt_vbuc1_then_la1 allocation: reg byte x [ main::i#2 main::i#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsyy_lt_vbuc1_then_la1 allocation: reg byte y [ main::i#2 main::i#1 ]
MISSING FRAGMENTS
vbsxx_lt_vbuc1_then_la1(main:: vbsxx=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 )
vbsyy_lt_vbuc1_then_la1(main:: vbsyy=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 )
Statement [6] if((signed byte) main::i#2<(byte/signed byte/word/signed word) 127) goto main::@2 [ main::i#2 main::j#2 ] ( main:2 [ main::i#2 main::j#2 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::j#2 main::j#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsxx_lt_vbuc1_then_la1(main:: vbsxx=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 ) allocation: reg byte x [ main::i#2 main::i#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsyy_lt_vbuc1_then_la1(main:: vbsyy=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 ) allocation: reg byte y [ main::i#2 main::i#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsxx_lt_vbuc1_then_la1 allocation: reg byte x [ main::i#2 main::i#1 ]
Potential register analysis [6] if(main::i#2<127) goto main::@2 missing fragment vbsyy_lt_vbuc1_then_la1 allocation: reg byte y [ main::i#2 main::i#1 ]
MISSING FRAGMENTS
vbsxx_lt_vbuc1_then_la1(main:: vbsxx=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 )
vbsyy_lt_vbuc1_then_la1(main:: vbsyy=(signed byte) main::i#2 vbuc1=(byte/signed byte/word/signed word) 127 la1=(label) main::@2 )

View File

@ -3178,8 +3178,8 @@ divFACby10: {
}
REGISTER UPLIFT POTENTIAL REGISTERS
Potential register analysis [11] setFAC::w#1 ← ((word)) main::i#10 missing fragment vwuz1=_word_vbuxx(main:: vwuz1=(word) setFAC::w#1 vbuxx=(byte) main::i#10 ) allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_WORD:13 [ setFAC::w#3 setFAC::w#1 ]
Potential register analysis [11] setFAC::w#1 ← ((word)) main::i#10 missing fragment vwuz1=_word_vbuyy(main:: vwuz1=(word) setFAC::w#1 vbuyy=(byte) main::i#10 ) allocation: reg byte y [ main::i#10 main::i#1 ] zp ZP_WORD:13 [ setFAC::w#3 setFAC::w#1 ]
Potential register analysis [11] setFAC::w#1 ← ((word)) main::i#10 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_WORD:13 [ setFAC::w#3 setFAC::w#1 ]
Potential register analysis [11] setFAC::w#1 ← ((word)) main::i#10 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ main::i#10 main::i#1 ] zp ZP_WORD:13 [ setFAC::w#3 setFAC::w#1 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(main:: vwuz1=(word) setFAC::w#1 vbuxx=(byte) main::i#10 )
vwuz1=_word_vbuyy(main:: vwuz1=(word) setFAC::w#1 vbuyy=(byte) main::i#10 )

View File

@ -7643,8 +7643,8 @@ Removing always clobbered register reg byte a as potential for zp ZP_BYTE:9 [ in
Statement [49] *((const byte*) COLS#0+(byte/signed byte/word/signed word) 40 + (byte) init::i#2) ← (byte/signed byte/word/signed word) 11 [ init::i#2 ] ( main:2::init:5 [ init::i#2 ] ) always clobbers reg byte a
Statement [69] *((byte*) clear_screen::sc#2) ← (byte) ' ' [ clear_screen::sc#2 ] ( main:2::init:5::clear_screen:46 [ clear_screen::sc#2 ] main:2::init:5::clear_screen:65 [ clear_screen::sc#2 ] ) always clobbers reg byte a reg byte y
Statement [71] if((byte*) clear_screen::sc#1<(const byte*) SCREEN#0+(word/signed word) 1000) goto clear_screen::@1 [ clear_screen::sc#1 ] ( main:2::init:5::clear_screen:46 [ clear_screen::sc#1 ] main:2::init:5::clear_screen:65 [ clear_screen::sc#1 ] ) always clobbers reg byte a
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuxx(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuxx=(byte) gen_sintab::max#2 ) allocation: reg byte x [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuyy(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuyy=(byte) gen_sintab::max#2 ) allocation: reg byte y [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuxx=(byte) gen_sintab::max#2 )
vwuz1=_word_vbuyy(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuyy=(byte) gen_sintab::max#2 )
@ -7657,8 +7657,8 @@ Removing always clobbered register reg byte y as potential for zp ZP_BYTE:13 [ g
Removing always clobbered register reg byte x as potential for zp ZP_BYTE:14 [ gen_sintab::length#10 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:14 [ gen_sintab::length#10 ]
Statement [79] (word) setFAC::w#1 ← ((word)) (byte) gen_sintab::min#2 [ gen_sintab::length#10 gen_sintab::sintab#12 setFAC::w#1 progress_init::line#2 ] ( main:2::init:5::gen_sintab:59 [ gen_sintab::length#10 gen_sintab::sintab#12 setFAC::w#1 progress_init::line#2 ] main:2::init:5::gen_sintab:63 [ gen_sintab::length#10 gen_sintab::sintab#12 setFAC::w#1 progress_init::line#2 ] ) always clobbers reg byte a
Potential register analysis [98] setFAC::w#3 ← ((word)) gen_sintab::i#10 missing fragment vwuz1=_word_vbuxx(gen_sintab:: vwuz1=(word) setFAC::w#3 vbuxx=(byte) gen_sintab::i#10 ) allocation: zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ] reg byte x [ gen_sintab::i#10 gen_sintab::i#1 ]
Potential register analysis [98] setFAC::w#3 ← ((word)) gen_sintab::i#10 missing fragment vwuz1=_word_vbuyy(gen_sintab:: vwuz1=(word) setFAC::w#3 vbuyy=(byte) gen_sintab::i#10 ) allocation: zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ] reg byte y [ gen_sintab::i#10 gen_sintab::i#1 ]
Potential register analysis [98] setFAC::w#3 ← ((word)) gen_sintab::i#10 missing fragment vwuz1=_word_vbuxx allocation: zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ] reg byte x [ gen_sintab::i#10 gen_sintab::i#1 ]
Potential register analysis [98] setFAC::w#3 ← ((word)) gen_sintab::i#10 missing fragment vwuz1=_word_vbuyy allocation: zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ] reg byte y [ gen_sintab::i#10 gen_sintab::i#1 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(gen_sintab:: vwuz1=(word) setFAC::w#3 vbuxx=(byte) gen_sintab::i#10 )
vwuz1=_word_vbuyy(gen_sintab:: vwuz1=(word) setFAC::w#3 vbuyy=(byte) gen_sintab::i#10 )
@ -7669,7 +7669,7 @@ Statement [104] (word) setFAC::w#4 ← ((word)) (byte) gen_sintab::length#10 [ g
Statement [116] (word) getFAC::return#2 ← (word) getFAC::return#0 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 getFAC::return#2 ] ( main:2::init:5::gen_sintab:59 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 getFAC::return#2 ] main:2::init:5::gen_sintab:63 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 getFAC::return#2 ] ) always clobbers reg byte a
Statement [117] (word~) gen_sintab::$23 ← (word) getFAC::return#2 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 gen_sintab::$23 ] ( main:2::init:5::gen_sintab:59 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 gen_sintab::$23 ] main:2::init:5::gen_sintab:63 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 gen_sintab::$23 ] ) always clobbers reg byte a
Statement [118] (byte~) gen_sintab::$24 ← ((byte)) (word~) gen_sintab::$23 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 gen_sintab::$24 ] ( main:2::init:5::gen_sintab:59 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 gen_sintab::$24 ] main:2::init:5::gen_sintab:63 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_idx#34 progress_cursor#34 gen_sintab::$24 ] ) always clobbers reg byte a
Potential register analysis [119] *(gen_sintab::sintab#12 + gen_sintab::i#10) ← gen_sintab::$24 missing fragment pbuz1_derefidx_vbuxx=vbuyy(gen_sintab:: pbuz1=(byte*) gen_sintab::sintab#12 vbuxx=(byte) gen_sintab::i#10 vbuyy=(byte~) gen_sintab::$24 ) allocation: zp ZP_WORD:15 [ gen_sintab::sintab#12 ] reg byte y [ gen_sintab::$24 ] reg byte x [ gen_sintab::i#10 gen_sintab::i#1 ]
Potential register analysis [119] *(gen_sintab::sintab#12 + gen_sintab::i#10) ← gen_sintab::$24 missing fragment pbuz1_derefidx_vbuxx=vbuyy allocation: zp ZP_WORD:15 [ gen_sintab::sintab#12 ] reg byte y [ gen_sintab::$24 ] reg byte x [ gen_sintab::i#10 gen_sintab::i#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuxx=vbuyy(gen_sintab:: pbuz1=(byte*) gen_sintab::sintab#12 vbuxx=(byte) gen_sintab::i#10 vbuyy=(byte~) gen_sintab::$24 )
Statement [126] *((byte*) progress_cursor#34) ← *((const byte[]) progress_inc::progress_chars#0+(byte/signed byte/word/signed word) 8) [ progress_cursor#34 ] ( main:2::init:5::gen_sintab:59::progress_inc:120 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_cursor#34 ] main:2::init:5::gen_sintab:63::progress_inc:120 [ gen_sintab::length#10 gen_sintab::sintab#12 gen_sintab::i#10 progress_cursor#34 ] ) always clobbers reg byte a reg byte y
@ -7695,8 +7695,8 @@ Statement [176] (byte*) gen_chargen_sprite::sprite#0 ← (byte*) gen_sprites::sp
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:33 [ gen_sprites::i#2 gen_sprites::i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:64 [ gen_chargen_sprite::ch#0 ]
Statement [178] (byte*) gen_sprites::spr#1 ← (byte*) gen_sprites::spr#2 + (byte/signed byte/word/signed word) 64 [ gen_sprites::i#2 gen_sprites::spr#1 ] ( main:2::init:5::gen_sprites:55 [ gen_sprites::i#2 gen_sprites::spr#1 ] ) always clobbers reg byte a
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuxx(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuxx=(byte) gen_chargen_sprite::ch#0 ) allocation: reg byte x [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuyy(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuyy=(byte) gen_chargen_sprite::ch#0 ) allocation: reg byte y [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuxx=(byte) gen_chargen_sprite::ch#0 )
vwuz1=_word_vbuyy(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuyy=(byte) gen_chargen_sprite::ch#0 )
@ -7715,8 +7715,8 @@ Statement [195] (byte~) gen_chargen_sprite::$6 ← (byte) gen_chargen_sprite::s_
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:39 [ gen_chargen_sprite::c#3 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:42 [ gen_chargen_sprite::b#2 gen_chargen_sprite::b#1 ]
Statement [196] (byte) gen_chargen_sprite::s_gen#1 ← (byte~) gen_chargen_sprite::$6 | (byte) gen_chargen_sprite::c#3 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::s_gen_cnt#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::s_gen_cnt#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ) always clobbers reg byte a
Potential register analysis [199] *(gen_chargen_sprite::sprite#3 + 0) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 0 vbuxx=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [199] *(gen_chargen_sprite::sprite#3 + 0) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuyy(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 0 vbuyy=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte y [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [199] *(gen_chargen_sprite::sprite#3 + 0) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [199] *(gen_chargen_sprite::sprite#3 + 0) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuyy allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte y [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 0 vbuxx=(byte) gen_chargen_sprite::s_gen#1 )
pbuz1_derefidx_vbuc1=vbuyy(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 0 vbuyy=(byte) gen_chargen_sprite::s_gen#1 )
@ -7728,11 +7728,11 @@ Removing always clobbered register reg byte y as potential for zp ZP_BYTE:38 [ g
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:39 [ gen_chargen_sprite::c#3 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:42 [ gen_chargen_sprite::b#2 gen_chargen_sprite::b#1 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:40 [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [200] *(gen_chargen_sprite::sprite#3 + 3) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 3 vbuxx=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [200] *(gen_chargen_sprite::sprite#3 + 3) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 3 vbuxx=(byte) gen_chargen_sprite::s_gen#1 )
Statement [200] *((byte*) gen_chargen_sprite::sprite#3 + (byte/signed byte/word/signed word) 3) ← (byte) gen_chargen_sprite::s_gen#1 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ) always clobbers reg byte a reg byte y
Potential register analysis [201] *(gen_chargen_sprite::sprite#3 + 6) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 6 vbuxx=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [201] *(gen_chargen_sprite::sprite#3 + 6) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 6 vbuxx=(byte) gen_chargen_sprite::s_gen#1 )
Statement [201] *((byte*) gen_chargen_sprite::sprite#3 + (byte/signed byte/word/signed word) 6) ← (byte) gen_chargen_sprite::s_gen#1 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 ] ) always clobbers reg byte a reg byte y
@ -7764,8 +7764,8 @@ Statement [48] *((const byte*) COLS#0 + (byte) init::i#2) ← (byte/signed byte/
Statement [49] *((const byte*) COLS#0+(byte/signed byte/word/signed word) 40 + (byte) init::i#2) ← (byte/signed byte/word/signed word) 11 [ init::i#2 ] ( main:2::init:5 [ init::i#2 ] ) always clobbers reg byte a
Statement [69] *((byte*) clear_screen::sc#2) ← (byte) ' ' [ clear_screen::sc#2 ] ( main:2::init:5::clear_screen:46 [ clear_screen::sc#2 ] main:2::init:5::clear_screen:65 [ clear_screen::sc#2 ] ) always clobbers reg byte a reg byte y
Statement [71] if((byte*) clear_screen::sc#1<(const byte*) SCREEN#0+(word/signed word) 1000) goto clear_screen::@1 [ clear_screen::sc#1 ] ( main:2::init:5::clear_screen:46 [ clear_screen::sc#1 ] main:2::init:5::clear_screen:65 [ clear_screen::sc#1 ] ) always clobbers reg byte a
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuxx(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuxx=(byte) gen_sintab::max#2 ) allocation: reg byte x [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuyy(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuyy=(byte) gen_sintab::max#2 ) allocation: reg byte y [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
Potential register analysis [74] setFAC::w#0 ← ((word)) gen_sintab::max#2 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ gen_sintab::max#2 ] zp ZP_WORD:29 [ setFAC::w#5 setFAC::w#0 setFAC::w#3 setFAC::w#4 setFAC::w#1 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuxx=(byte) gen_sintab::max#2 )
vwuz1=_word_vbuyy(gen_sintab:: vwuz1=(word) setFAC::w#0 vbuyy=(byte) gen_sintab::max#2 )
@ -7797,8 +7797,8 @@ Statement [163] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#5 [ prepa
Statement asm { ldx$fe ldy$ff jsr$bbd4 } always clobbers reg byte x reg byte y
Statement [176] (byte*) gen_chargen_sprite::sprite#0 ← (byte*) gen_sprites::spr#2 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::ch#0 gen_chargen_sprite::sprite#0 ] ( main:2::init:5::gen_sprites:55 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::ch#0 gen_chargen_sprite::sprite#0 ] ) always clobbers reg byte a
Statement [178] (byte*) gen_sprites::spr#1 ← (byte*) gen_sprites::spr#2 + (byte/signed byte/word/signed word) 64 [ gen_sprites::i#2 gen_sprites::spr#1 ] ( main:2::init:5::gen_sprites:55 [ gen_sprites::i#2 gen_sprites::spr#1 ] ) always clobbers reg byte a
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuxx(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuxx=(byte) gen_chargen_sprite::ch#0 ) allocation: reg byte x [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuyy(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuyy=(byte) gen_chargen_sprite::ch#0 ) allocation: reg byte y [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
Potential register analysis [182] gen_chargen_sprite::$0 ← ((word)) gen_chargen_sprite::ch#0 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ gen_chargen_sprite::ch#0 ] zp ZP_WORD:65 [ gen_chargen_sprite::$0 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuxx=(byte) gen_chargen_sprite::ch#0 )
vwuz1=_word_vbuyy(gen_chargen_sprite:: vwuz1=(word~) gen_chargen_sprite::$0 vbuyy=(byte) gen_chargen_sprite::ch#0 )
@ -7810,15 +7810,15 @@ Statement [188] (byte) gen_chargen_sprite::bits#0 ← *((byte*) gen_chargen_spri
Statement [190] (byte~) gen_chargen_sprite::$3 ← (byte) gen_chargen_sprite::bits#2 & (byte/word/signed word) 128 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen_cnt#4 gen_chargen_sprite::sprite#10 gen_chargen_sprite::x#6 gen_chargen_sprite::$3 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen_cnt#4 gen_chargen_sprite::sprite#10 gen_chargen_sprite::x#6 gen_chargen_sprite::$3 ] ) always clobbers reg byte a
Statement [195] (byte~) gen_chargen_sprite::$6 ← (byte) gen_chargen_sprite::s_gen#3 << (byte/signed byte/word/signed word) 1 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::s_gen_cnt#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::$6 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::s_gen_cnt#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::$6 ] ) always clobbers reg byte a
Statement [196] (byte) gen_chargen_sprite::s_gen#1 ← (byte~) gen_chargen_sprite::$6 | (byte) gen_chargen_sprite::c#3 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::s_gen_cnt#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::s_gen_cnt#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ) always clobbers reg byte a
Potential register analysis [199] *(gen_chargen_sprite::sprite#3 + 0) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 0 vbuxx=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [199] *(gen_chargen_sprite::sprite#3 + 0) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 0 vbuxx=(byte) gen_chargen_sprite::s_gen#1 )
Statement [199] *((byte*) gen_chargen_sprite::sprite#3 + (byte/signed byte/word/signed word) 0) ← (byte) gen_chargen_sprite::s_gen#1 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ) always clobbers reg byte a reg byte y
Potential register analysis [200] *(gen_chargen_sprite::sprite#3 + 3) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 3 vbuxx=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [200] *(gen_chargen_sprite::sprite#3 + 3) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 3 vbuxx=(byte) gen_chargen_sprite::s_gen#1 )
Statement [200] *((byte*) gen_chargen_sprite::sprite#3 + (byte/signed byte/word/signed word) 3) ← (byte) gen_chargen_sprite::s_gen#1 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 gen_chargen_sprite::s_gen#1 ] ) always clobbers reg byte a reg byte y
Potential register analysis [201] *(gen_chargen_sprite::sprite#3 + 6) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 6 vbuxx=(byte) gen_chargen_sprite::s_gen#1 ) allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
Potential register analysis [201] *(gen_chargen_sprite::sprite#3 + 6) ← gen_chargen_sprite::s_gen#1 missing fragment pbuz1_derefidx_vbuc1=vbuxx allocation: zp ZP_WORD:43 [ gen_chargen_sprite::sprite#3 gen_chargen_sprite::sprite#10 gen_chargen_sprite::sprite#11 gen_chargen_sprite::sprite#0 gen_chargen_sprite::sprite#2 gen_chargen_sprite::sprite#4 gen_chargen_sprite::sprite#1 ] reg byte x [ gen_chargen_sprite::s_gen#3 gen_chargen_sprite::s_gen#5 gen_chargen_sprite::s_gen#6 gen_chargen_sprite::s_gen#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuc1=vbuxx(gen_chargen_sprite:: pbuz1=(byte*) gen_chargen_sprite::sprite#3 vbuc1=(byte/signed byte/word/signed word) 6 vbuxx=(byte) gen_chargen_sprite::s_gen#1 )
Statement [201] *((byte*) gen_chargen_sprite::sprite#3 + (byte/signed byte/word/signed word) 6) ← (byte) gen_chargen_sprite::s_gen#1 [ gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 ] ( main:2::init:5::gen_sprites:55::gen_chargen_sprite:177 [ gen_sprites::i#2 gen_sprites::spr#2 gen_chargen_sprite::chargen#0 gen_chargen_sprite::y#2 gen_chargen_sprite::bits#2 gen_chargen_sprite::x#6 gen_chargen_sprite::c#3 gen_chargen_sprite::b#2 gen_chargen_sprite::sprite#3 ] ) always clobbers reg byte a reg byte y

View File

@ -8647,10 +8647,10 @@ Potential register analysis [21] if(main::a#10>=*(main::cs#0 + main::i#10)) goto
Potential register analysis [21] if(main::a#10>=*(main::cs#0 + main::i#10)) goto main::@4 missing fragment vbuyy_ge_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
Potential register analysis [21] if(main::a#10>=*(main::cs#0 + main::i#10)) goto main::@4 missing fragment vbuyy_ge_pbuc1_derefidx_vbuyy_then_la1 allocation: reg byte y [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1
vbuyy_ge_pbuc1_derefidx_vbuz1_then_la1
vbuyy_ge_pbuc1_derefidx_vbuxx_then_la1
vbuyy_ge_pbuc1_derefidx_vbuyy_then_la1
vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b4_from_b47 )
vbuyy_ge_pbuc1_derefidx_vbuz1_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuz1=(byte) main::i#10 la1=(label) main::b4_from_b47 )
vbuyy_ge_pbuc1_derefidx_vbuxx_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b4_from_b47 )
vbuyy_ge_pbuc1_derefidx_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 la1=(label) main::b4_from_b47 )
Statement [21] if((byte) main::a#10>=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@4 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:39 [ main::b#0 ]
Statement [28] if((byte) main::a#10>=(byte) main::a#10) goto main::@5 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
@ -8663,28 +8663,28 @@ Potential register analysis [51] if(main::a#10<=*(main::cs#0 + main::i#10)) goto
Potential register analysis [51] if(main::a#10<=*(main::cs#0 + main::i#10)) goto main::@8 missing fragment vbuyy_le_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
Potential register analysis [51] if(main::a#10<=*(main::cs#0 + main::i#10)) goto main::@8 missing fragment vbuyy_le_pbuc1_derefidx_vbuyy_then_la1 allocation: reg byte y [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_le_pbuc1_derefidx_vbuxx_then_la1
vbuyy_le_pbuc1_derefidx_vbuz1_then_la1
vbuyy_le_pbuc1_derefidx_vbuxx_then_la1
vbuyy_le_pbuc1_derefidx_vbuyy_then_la1
vbuz1_le_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b8_from_b52 )
vbuyy_le_pbuc1_derefidx_vbuz1_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuz1=(byte) main::i#10 la1=(label) main::b8_from_b52 )
vbuyy_le_pbuc1_derefidx_vbuxx_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b8_from_b52 )
vbuyy_le_pbuc1_derefidx_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 la1=(label) main::b8_from_b52 )
Statement [51] if((byte) main::a#10<=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@8 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [73] (byte*~) char_cursor#138 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 char_cursor#138 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 char_cursor#138 ] ) always clobbers reg byte a
Potential register analysis [75] if(main::a#10>55) goto main::@11 missing fragment vbuxx_gt_vbuc1_then_la1 allocation: reg byte x [ main::a#10 main::a#1 ]
Potential register analysis [75] if(main::a#10>55) goto main::@11 missing fragment vbuyy_gt_vbuc1_then_la1 allocation: reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuxx_gt_vbuc1_then_la1
vbuyy_gt_vbuc1_then_la1
vbuxx_gt_vbuc1_then_la1(main:: vbuxx=(byte) main::a#10 vbuc1=(byte/signed byte/word/signed word) 55 la1=(label) main::b11_from_b56 )
vbuyy_gt_vbuc1_then_la1(main:: vbuyy=(byte) main::a#10 vbuc1=(byte/signed byte/word/signed word) 55 la1=(label) main::b11_from_b56 )
Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word) 55) goto main::@11 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Potential register analysis [81] if(main::a#10>*(main::cs#0 + main::i#10)) goto main::@12 missing fragment vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
Potential register analysis [81] if(main::a#10>*(main::cs#0 + main::i#10)) goto main::@12 missing fragment vbuyy_gt_pbuc1_derefidx_vbuz1_then_la1 allocation: zp ZP_BYTE:3 [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
Potential register analysis [81] if(main::a#10>*(main::cs#0 + main::i#10)) goto main::@12 missing fragment vbuyy_gt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
Potential register analysis [81] if(main::a#10>*(main::cs#0 + main::i#10)) goto main::@12 missing fragment vbuyy_gt_pbuc1_derefidx_vbuyy_then_la1 allocation: reg byte y [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1
vbuyy_gt_pbuc1_derefidx_vbuz1_then_la1
vbuyy_gt_pbuc1_derefidx_vbuxx_then_la1
vbuyy_gt_pbuc1_derefidx_vbuyy_then_la1
vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b12_from_b57 )
vbuyy_gt_pbuc1_derefidx_vbuz1_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuz1=(byte) main::i#10 la1=(label) main::b12_from_b57 )
vbuyy_gt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b12_from_b57 )
vbuyy_gt_pbuc1_derefidx_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 la1=(label) main::b12_from_b57 )
Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [88] if((byte) main::a#10>(byte) main::a#10) goto main::@13 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [103] (byte*~) char_cursor#142 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 char_cursor#142 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 char_cursor#142 ] ) always clobbers reg byte a
@ -8693,16 +8693,16 @@ Potential register analysis [111] if(main::a#10<*(main::cs#0 + main::i#10)) goto
Potential register analysis [111] if(main::a#10<*(main::cs#0 + main::i#10)) goto main::@16 missing fragment vbuyy_lt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
Potential register analysis [111] if(main::a#10<*(main::cs#0 + main::i#10)) goto main::@16 missing fragment vbuyy_lt_pbuc1_derefidx_vbuyy_then_la1 allocation: reg byte y [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1
vbuyy_lt_pbuc1_derefidx_vbuz1_then_la1
vbuyy_lt_pbuc1_derefidx_vbuxx_then_la1
vbuyy_lt_pbuc1_derefidx_vbuyy_then_la1
vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b16_from_b62 )
vbuyy_lt_pbuc1_derefidx_vbuz1_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuz1=(byte) main::i#10 la1=(label) main::b16_from_b62 )
vbuyy_lt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b16_from_b62 )
vbuyy_lt_pbuc1_derefidx_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 la1=(label) main::b16_from_b62 )
Statement [111] if((byte) main::a#10<*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@16 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Potential register analysis [118] if(main::a#10<main::a#10) goto main::@17 missing fragment vbuxx_lt_vbuxx_then_la1 allocation: reg byte x [ main::a#10 main::a#1 ]
Potential register analysis [118] if(main::a#10<main::a#10) goto main::@17 missing fragment vbuyy_lt_vbuyy_then_la1 allocation: reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuxx_lt_vbuxx_then_la1
vbuyy_lt_vbuyy_then_la1
vbuxx_lt_vbuxx_then_la1(main:: vbuxx=(byte) main::a#10 la1=(label) main::b17_from_b63 )
vbuyy_lt_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 la1=(label) main::b17_from_b63 )
Statement [118] if((byte) main::a#10<(byte) main::a#10) goto main::@17 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [133] (byte*~) char_cursor#146 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 printu::a#16 printu::b#16 printu::res#16 char_cursor#146 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 printu::a#16 printu::b#16 printu::res#16 char_cursor#146 ] ) always clobbers reg byte a
Potential register analysis [141] if(main::a#10!=*(main::cs#0 + main::i#10)) goto main::@20 missing fragment vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
@ -8710,14 +8710,14 @@ Potential register analysis [141] if(main::a#10!=*(main::cs#0 + main::i#10)) got
Potential register analysis [141] if(main::a#10!=*(main::cs#0 + main::i#10)) goto main::@20 missing fragment vbuyy_neq_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
Potential register analysis [141] if(main::a#10!=*(main::cs#0 + main::i#10)) goto main::@20 missing fragment vbuyy_neq_pbuc1_derefidx_vbuyy_then_la1 allocation: reg byte y [ main::i#10 main::i#1 ] reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1
vbuyy_neq_pbuc1_derefidx_vbuz1_then_la1
vbuyy_neq_pbuc1_derefidx_vbuxx_then_la1
vbuyy_neq_pbuc1_derefidx_vbuyy_then_la1
vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b20_from_b67 )
vbuyy_neq_pbuc1_derefidx_vbuz1_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuz1=(byte) main::i#10 la1=(label) main::b20_from_b67 )
vbuyy_neq_pbuc1_derefidx_vbuxx_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b20_from_b67 )
vbuyy_neq_pbuc1_derefidx_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 la1=(label) main::b20_from_b67 )
Statement [141] if((byte) main::a#10!=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@20 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ) always clobbers reg byte a
Potential register analysis [148] if(main::a#10!=main::a#10) goto main::@21 missing fragment vbuyy_neq_vbuyy_then_la1 allocation: reg byte y [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuyy_neq_vbuyy_then_la1
vbuyy_neq_vbuyy_then_la1(main:: vbuyy=(byte) main::a#10 la1=(label) main::b21_from_b68 )
Statement [148] if((byte) main::a#10!=(byte) main::a#10) goto main::@21 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ) always clobbers reg byte a
Statement [157] (byte) main::a#1 ← (byte) main::a#10 + (byte/signed byte/word/signed word) 48 [ main::i#10 main::a#1 line_cursor#1 ] ( main:2 [ main::i#10 main::a#1 line_cursor#1 ] ) always clobbers reg byte a
Statement [162] (byte*~) char_cursor#137 ← (byte*) line_cursor#1 [ main::a#1 char_cursor#137 main::i#1 line_cursor#1 ] ( main:2 [ main::a#1 char_cursor#137 main::i#1 line_cursor#1 ] ) always clobbers reg byte a
@ -8740,7 +8740,7 @@ Statement [204] if((byte*) print_cls::sc#1!=(word/signed word) 1024+(word/signed
Statement [7] (byte) main::b#0 ← (byte/word/signed word) 206 - (byte) main::a#10 [ main::a#10 char_cursor#114 main::i#10 line_cursor#21 main::b#0 ] ( main:2 [ main::a#10 char_cursor#114 main::i#10 line_cursor#21 main::b#0 ] ) always clobbers reg byte a
Potential register analysis [21] if(main::a#10>=*(main::cs#0 + main::i#10)) goto main::@4 missing fragment vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1
vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b4_from_b47 )
Statement [21] if((byte) main::a#10>=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@4 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [25] (byte) printu::b#2 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#21 main::b#0 main::r#42 printu::a#2 printu::b#2 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 main::r#42 printu::a#2 printu::b#2 char_cursor#52 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ main::r#42 ]
@ -8748,7 +8748,7 @@ Statement [28] if((byte) main::a#10>=(byte) main::a#10) goto main::@5 [ main::a#
Statement [43] (byte*~) char_cursor#154 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#4 printu::b#4 printu::res#4 char_cursor#154 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#4 printu::b#4 printu::res#4 char_cursor#154 ] ) always clobbers reg byte a
Potential register analysis [51] if(main::a#10<=*(main::cs#0 + main::i#10)) goto main::@8 missing fragment vbuz1_le_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_le_pbuc1_derefidx_vbuxx_then_la1
vbuz1_le_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b8_from_b52 )
Statement [51] if((byte) main::a#10<=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@8 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [55] (byte) printu::b#6 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#46 printu::a#6 printu::b#6 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#46 printu::a#6 printu::b#6 char_cursor#52 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:10 [ main::r#46 ]
@ -8756,11 +8756,11 @@ Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#
Statement [73] (byte*~) char_cursor#138 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 char_cursor#138 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 char_cursor#138 ] ) always clobbers reg byte a
Potential register analysis [75] if(main::a#10>55) goto main::@11 missing fragment vbuxx_gt_vbuc1_then_la1 allocation: reg byte x [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuxx_gt_vbuc1_then_la1
vbuxx_gt_vbuc1_then_la1(main:: vbuxx=(byte) main::a#10 vbuc1=(byte/signed byte/word/signed word) 55 la1=(label) main::b11_from_b56 )
Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word) 55) goto main::@11 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Potential register analysis [81] if(main::a#10>*(main::cs#0 + main::i#10)) goto main::@12 missing fragment vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1
vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b12_from_b57 )
Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [85] (byte) printu::b#10 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#50 printu::a#10 printu::b#10 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#50 printu::a#10 printu::b#10 char_cursor#52 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:14 [ main::r#50 ]
@ -8768,18 +8768,18 @@ Statement [88] if((byte) main::a#10>(byte) main::a#10) goto main::@13 [ main::a#
Statement [103] (byte*~) char_cursor#142 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 char_cursor#142 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 char_cursor#142 ] ) always clobbers reg byte a
Potential register analysis [111] if(main::a#10<*(main::cs#0 + main::i#10)) goto main::@16 missing fragment vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1
vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b16_from_b62 )
Statement [111] if((byte) main::a#10<*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@16 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [115] (byte) printu::b#14 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#54 printu::a#14 printu::b#14 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#54 printu::a#14 printu::b#14 char_cursor#52 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:18 [ main::r#54 ]
Potential register analysis [118] if(main::a#10<main::a#10) goto main::@17 missing fragment vbuxx_lt_vbuxx_then_la1 allocation: reg byte x [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuxx_lt_vbuxx_then_la1
vbuxx_lt_vbuxx_then_la1(main:: vbuxx=(byte) main::a#10 la1=(label) main::b17_from_b63 )
Statement [118] if((byte) main::a#10<(byte) main::a#10) goto main::@17 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [133] (byte*~) char_cursor#146 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 printu::a#16 printu::b#16 printu::res#16 char_cursor#146 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 printu::a#16 printu::b#16 printu::res#16 char_cursor#146 ] ) always clobbers reg byte a
Potential register analysis [141] if(main::a#10!=*(main::cs#0 + main::i#10)) goto main::@20 missing fragment vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1
vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b20_from_b67 )
Statement [141] if((byte) main::a#10!=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@20 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [145] (byte) printu::b#18 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::r#58 printu::a#18 printu::b#18 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::r#58 printu::a#18 printu::b#18 char_cursor#52 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:22 [ main::r#58 ]
@ -8798,42 +8798,42 @@ Statement [204] if((byte*) print_cls::sc#1!=(word/signed word) 1024+(word/signed
Statement [7] (byte) main::b#0 ← (byte/word/signed word) 206 - (byte) main::a#10 [ main::a#10 char_cursor#114 main::i#10 line_cursor#21 main::b#0 ] ( main:2 [ main::a#10 char_cursor#114 main::i#10 line_cursor#21 main::b#0 ] ) always clobbers reg byte a
Potential register analysis [21] if(main::a#10>=*(main::cs#0 + main::i#10)) goto main::@4 missing fragment vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1
vbuz1_ge_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b4_from_b47 )
Statement [21] if((byte) main::a#10>=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@4 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [25] (byte) printu::b#2 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#21 main::b#0 main::r#42 printu::a#2 printu::b#2 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 main::r#42 printu::a#2 printu::b#2 char_cursor#52 ] ) always clobbers reg byte a
Statement [28] if((byte) main::a#10>=(byte) main::a#10) goto main::@5 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#21 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [43] (byte*~) char_cursor#154 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#4 printu::b#4 printu::res#4 char_cursor#154 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#4 printu::b#4 printu::res#4 char_cursor#154 ] ) always clobbers reg byte a
Potential register analysis [51] if(main::a#10<=*(main::cs#0 + main::i#10)) goto main::@8 missing fragment vbuz1_le_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_le_pbuc1_derefidx_vbuxx_then_la1
vbuz1_le_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b8_from_b52 )
Statement [51] if((byte) main::a#10<=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@8 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [55] (byte) printu::b#6 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#46 printu::a#6 printu::b#6 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#46 printu::a#6 printu::b#6 char_cursor#52 ] ) always clobbers reg byte a
Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [73] (byte*~) char_cursor#138 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 char_cursor#138 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 char_cursor#138 ] ) always clobbers reg byte a
Potential register analysis [75] if(main::a#10>55) goto main::@11 missing fragment vbuxx_gt_vbuc1_then_la1 allocation: reg byte x [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuxx_gt_vbuc1_then_la1
vbuxx_gt_vbuc1_then_la1(main:: vbuxx=(byte) main::a#10 vbuc1=(byte/signed byte/word/signed word) 55 la1=(label) main::b11_from_b56 )
Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word) 55) goto main::@11 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Potential register analysis [81] if(main::a#10>*(main::cs#0 + main::i#10)) goto main::@12 missing fragment vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1
vbuz1_gt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b12_from_b57 )
Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [85] (byte) printu::b#10 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#50 printu::a#10 printu::b#10 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#50 printu::a#10 printu::b#10 char_cursor#52 ] ) always clobbers reg byte a
Statement [88] if((byte) main::a#10>(byte) main::a#10) goto main::@13 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [103] (byte*~) char_cursor#142 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 char_cursor#142 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 char_cursor#142 ] ) always clobbers reg byte a
Potential register analysis [111] if(main::a#10<*(main::cs#0 + main::i#10)) goto main::@16 missing fragment vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1
vbuz1_lt_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b16_from_b62 )
Statement [111] if((byte) main::a#10<*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@16 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [115] (byte) printu::b#14 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#54 printu::a#14 printu::b#14 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 main::r#54 printu::a#14 printu::b#14 char_cursor#52 ] ) always clobbers reg byte a
Potential register analysis [118] if(main::a#10<main::a#10) goto main::@17 missing fragment vbuxx_lt_vbuxx_then_la1 allocation: reg byte x [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuxx_lt_vbuxx_then_la1
vbuxx_lt_vbuxx_then_la1(main:: vbuxx=(byte) main::a#10 la1=(label) main::b17_from_b63 )
Statement [118] if((byte) main::a#10<(byte) main::a#10) goto main::@17 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::b#0 char_cursor#52 ] ) always clobbers reg byte a
Statement [133] (byte*~) char_cursor#146 ← (byte*) line_cursor#1 [ main::a#10 main::i#10 line_cursor#1 printu::a#16 printu::b#16 printu::res#16 char_cursor#146 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 printu::a#16 printu::b#16 printu::res#16 char_cursor#146 ] ) always clobbers reg byte a
Potential register analysis [141] if(main::a#10!=*(main::cs#0 + main::i#10)) goto main::@20 missing fragment vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1 allocation: reg byte x [ main::i#10 main::i#1 ] zp ZP_BYTE:2 [ main::a#10 main::a#1 ]
MISSING FRAGMENTS
vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1
vbuz1_neq_pbuc1_derefidx_vbuxx_then_la1(main:: vbuz1=(byte) main::a#10 pbuc1=(const byte[5]) main::cs#0 vbuxx=(byte) main::i#10 la1=(label) main::b20_from_b67 )
Statement [141] if((byte) main::a#10!=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@20 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ) always clobbers reg byte a reg byte y
Statement [145] (byte) printu::b#18 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 line_cursor#1 main::r#58 printu::a#18 printu::b#18 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 main::r#58 printu::a#18 printu::b#18 char_cursor#52 ] ) always clobbers reg byte a
Statement [148] if((byte) main::a#10!=(byte) main::a#10) goto main::@21 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ( main:2 [ main::a#10 main::i#10 line_cursor#1 char_cursor#52 ] ) always clobbers reg byte a

View File

@ -8142,14 +8142,14 @@ Removing always clobbered register reg byte x as potential for zp ZP_BYTE:25 [ m
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:26 [ multiply_results_compare::b#2 multiply_results_compare::b#1 ]
Removing always clobbered register reg byte x as potential for zp ZP_BYTE:26 [ multiply_results_compare::b#2 multiply_results_compare::b#1 ]
Statement [136] (word) multiply::return#0 ← *((const byte*) multiply::memB#0) w= *((const byte*) multiply::memA#0) [ multiply::return#0 ] ( main:2::signed_multiply_results_compare:15::signed_multiply:27::multiply:115 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 signed_multiply_results_compare::ms#0 line_cursor#1 signed_multiply::a#0 signed_multiply::b#0 multiply::return#0 ] main:2::multiply_results_compare:13::multiply:160 [ line_cursor#27 char_cursor#27 multiply_results_compare::a#6 multiply_results_compare::b#2 multiply_results_compare::ms#0 multiply::return#0 ] ) always clobbers reg byte a
Potential register analysis [140] slow_signed_multiply::m#1 ← slow_signed_multiply::m#3 - slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_minus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#1 vbsyy=(signed byte) slow_signed_multiply::b#0 ) allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
Potential register analysis [140] slow_signed_multiply::m#1 ← slow_signed_multiply::m#3 - slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_minus_vbsyy allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
MISSING FRAGMENTS
vwsz1=vwsz1_minus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#1 vbsyy=(signed byte) slow_signed_multiply::b#0 )
Statement [140] (signed word) slow_signed_multiply::m#1 ← (signed word) slow_signed_multiply::m#3 - (signed byte) slow_signed_multiply::b#0 [ slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::i#2 slow_signed_multiply::m#1 ] ( main:2::signed_multiply_results_compare:15::slow_signed_multiply:22 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 line_cursor#1 slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::i#2 slow_signed_multiply::m#1 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:50 [ slow_signed_multiply::a#0 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:51 [ slow_signed_multiply::b#0 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:21 [ slow_signed_multiply::i#2 slow_signed_multiply::i#1 ]
Potential register analysis [147] slow_signed_multiply::m#2 ← slow_signed_multiply::m#5 + slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_plus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#2 vbsyy=(signed byte) slow_signed_multiply::b#0 ) allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
Potential register analysis [147] slow_signed_multiply::m#2 ← slow_signed_multiply::m#5 + slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_plus_vbsyy allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
MISSING FRAGMENTS
vwsz1=vwsz1_plus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#2 vbsyy=(signed byte) slow_signed_multiply::b#0 )
Statement [147] (signed word) slow_signed_multiply::m#2 ← (signed word) slow_signed_multiply::m#5 + (signed byte) slow_signed_multiply::b#0 [ slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::m#2 slow_signed_multiply::j#2 ] ( main:2::signed_multiply_results_compare:15::slow_signed_multiply:22 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 line_cursor#1 slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::m#2 slow_signed_multiply::j#2 ] ) always clobbers reg byte a
@ -8236,11 +8236,11 @@ Statement [127] (byte/signed byte/word/signed word~) signed_multiply::$17 ← (b
Statement [130] (signed word) signed_multiply::return#0 ← ((signed word)) (word) signed_multiply::m#4 [ signed_multiply::return#0 ] ( main:2::signed_multiply_results_compare:15::signed_multiply:27 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 signed_multiply_results_compare::ms#0 line_cursor#1 signed_multiply::return#0 ] ) always clobbers reg byte a
Statement asm { ldamemA stasm1+1 stasm3+1 eor#$ff stasm2+1 stasm4+1 ldxmemB sec sm1: ldamul_sqr1_lo,x sm2: sbcmul_sqr2_lo,x stamemA sm3: ldamul_sqr1_hi,x sm4: sbcmul_sqr2_hi,x stamemB } always clobbers reg byte a reg byte x
Statement [136] (word) multiply::return#0 ← *((const byte*) multiply::memB#0) w= *((const byte*) multiply::memA#0) [ multiply::return#0 ] ( main:2::signed_multiply_results_compare:15::signed_multiply:27::multiply:115 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 signed_multiply_results_compare::ms#0 line_cursor#1 signed_multiply::a#0 signed_multiply::b#0 multiply::return#0 ] main:2::multiply_results_compare:13::multiply:160 [ line_cursor#27 char_cursor#27 multiply_results_compare::a#6 multiply_results_compare::b#2 multiply_results_compare::ms#0 multiply::return#0 ] ) always clobbers reg byte a
Potential register analysis [140] slow_signed_multiply::m#1 ← slow_signed_multiply::m#3 - slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_minus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#1 vbsyy=(signed byte) slow_signed_multiply::b#0 ) allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
Potential register analysis [140] slow_signed_multiply::m#1 ← slow_signed_multiply::m#3 - slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_minus_vbsyy allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
MISSING FRAGMENTS
vwsz1=vwsz1_minus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#1 vbsyy=(signed byte) slow_signed_multiply::b#0 )
Statement [140] (signed word) slow_signed_multiply::m#1 ← (signed word) slow_signed_multiply::m#3 - (signed byte) slow_signed_multiply::b#0 [ slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::i#2 slow_signed_multiply::m#1 ] ( main:2::signed_multiply_results_compare:15::slow_signed_multiply:22 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 line_cursor#1 slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::i#2 slow_signed_multiply::m#1 ] ) always clobbers reg byte a
Potential register analysis [147] slow_signed_multiply::m#2 ← slow_signed_multiply::m#5 + slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_plus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#2 vbsyy=(signed byte) slow_signed_multiply::b#0 ) allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
Potential register analysis [147] slow_signed_multiply::m#2 ← slow_signed_multiply::m#5 + slow_signed_multiply::b#0 missing fragment vwsz1=vwsz1_plus_vbsyy allocation: zp ZP_WORD:22 [ slow_signed_multiply::m#5 slow_signed_multiply::return#0 slow_signed_multiply::m#3 slow_signed_multiply::m#1 slow_signed_multiply::m#2 ] reg byte y [ slow_signed_multiply::b#0 ]
MISSING FRAGMENTS
vwsz1=vwsz1_plus_vbsyy(slow_signed_multiply:: vwsz1=(signed word) slow_signed_multiply::m#2 vbsyy=(signed byte) slow_signed_multiply::b#0 )
Statement [147] (signed word) slow_signed_multiply::m#2 ← (signed word) slow_signed_multiply::m#5 + (signed byte) slow_signed_multiply::b#0 [ slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::m#2 slow_signed_multiply::j#2 ] ( main:2::signed_multiply_results_compare:15::slow_signed_multiply:22 [ signed_multiply_results_compare::a#6 signed_multiply_results_compare::b#2 line_cursor#1 slow_signed_multiply::a#0 slow_signed_multiply::b#0 slow_signed_multiply::m#2 slow_signed_multiply::j#2 ] ) always clobbers reg byte a

View File

@ -2509,8 +2509,8 @@ Statement [31] *((const byte[]) YPOS#0+(byte/signed byte/word/signed word) 3)
Statement [32] (byte/word~) animate::$15 ← *((const byte[]) XPOS#0+(byte/signed byte/word/signed word) 3) + (byte/signed byte/word/signed word) 7 [ animate::$15 ] ( main:2::animate:9 [ animate::$15 ] ) always clobbers reg byte a
Statement [34] if(*((const byte[]) XPOS#0+(byte/signed byte/word/signed word) 3)<(byte/signed byte/word/signed word) 40) goto animate::@return [ ] ( main:2::animate:9 [ ] ) always clobbers reg byte a
Statement [35] (byte/signed byte/word/signed word~) animate::$18 ← *((const byte[]) XPOS#0+(byte/signed byte/word/signed word) 3) - (byte/signed byte/word/signed word) 40 [ animate::$18 ] ( main:2::animate:9 [ animate::$18 ] ) always clobbers reg byte a
Potential register analysis [46] *(render::colline#5 + render::x#2) ← render::col#0 missing fragment pbuz1_derefidx_vbuaa=vbuyy(render:: pbuz1=(byte*) render::colline#5 vbuaa=(byte) render::x#2 vbuyy=(byte) render::col#0 ) allocation: reg byte y [ render::col#0 ] reg byte a [ render::x#2 render::x#1 ] zp ZP_WORD:3 [ render::colline#5 render::colline#1 ]
Potential register analysis [46] *(render::colline#5 + render::x#2) ← render::col#0 missing fragment pbuz1_derefidx_vbuxx=vbuyy(render:: pbuz1=(byte*) render::colline#5 vbuxx=(byte) render::x#2 vbuyy=(byte) render::col#0 ) allocation: reg byte y [ render::col#0 ] reg byte x [ render::x#2 render::x#1 ] zp ZP_WORD:3 [ render::colline#5 render::colline#1 ]
Potential register analysis [46] *(render::colline#5 + render::x#2) ← render::col#0 missing fragment pbuz1_derefidx_vbuaa=vbuyy allocation: reg byte y [ render::col#0 ] reg byte a [ render::x#2 render::x#1 ] zp ZP_WORD:3 [ render::colline#5 render::colline#1 ]
Potential register analysis [46] *(render::colline#5 + render::x#2) ← render::col#0 missing fragment pbuz1_derefidx_vbuxx=vbuyy allocation: reg byte y [ render::col#0 ] reg byte x [ render::x#2 render::x#1 ] zp ZP_WORD:3 [ render::colline#5 render::colline#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuaa=vbuyy(render:: pbuz1=(byte*) render::colline#5 vbuaa=(byte) render::x#2 vbuyy=(byte) render::col#0 )
pbuz1_derefidx_vbuxx=vbuyy(render:: pbuz1=(byte*) render::colline#5 vbuxx=(byte) render::x#2 vbuyy=(byte) render::col#0 )
@ -2550,7 +2550,7 @@ Statement [31] *((const byte[]) YPOS#0+(byte/signed byte/word/signed word) 3)
Statement [32] (byte/word~) animate::$15 ← *((const byte[]) XPOS#0+(byte/signed byte/word/signed word) 3) + (byte/signed byte/word/signed word) 7 [ animate::$15 ] ( main:2::animate:9 [ animate::$15 ] ) always clobbers reg byte a
Statement [34] if(*((const byte[]) XPOS#0+(byte/signed byte/word/signed word) 3)<(byte/signed byte/word/signed word) 40) goto animate::@return [ ] ( main:2::animate:9 [ ] ) always clobbers reg byte a
Statement [35] (byte/signed byte/word/signed word~) animate::$18 ← *((const byte[]) XPOS#0+(byte/signed byte/word/signed word) 3) - (byte/signed byte/word/signed word) 40 [ animate::$18 ] ( main:2::animate:9 [ animate::$18 ] ) always clobbers reg byte a
Potential register analysis [46] *(render::colline#5 + render::x#2) ← render::col#0 missing fragment pbuz1_derefidx_vbuxx=vbuyy(render:: pbuz1=(byte*) render::colline#5 vbuxx=(byte) render::x#2 vbuyy=(byte) render::col#0 ) allocation: reg byte y [ render::col#0 ] reg byte x [ render::x#2 render::x#1 ] zp ZP_WORD:3 [ render::colline#5 render::colline#1 ]
Potential register analysis [46] *(render::colline#5 + render::x#2) ← render::col#0 missing fragment pbuz1_derefidx_vbuxx=vbuyy allocation: reg byte y [ render::col#0 ] reg byte x [ render::x#2 render::x#1 ] zp ZP_WORD:3 [ render::colline#5 render::colline#1 ]
MISSING FRAGMENTS
pbuz1_derefidx_vbuxx=vbuyy(render:: pbuz1=(byte*) render::colline#5 vbuxx=(byte) render::x#2 vbuyy=(byte) render::col#0 )
Statement [49] (byte*) render::colline#1 ← (byte*) render::colline#5 + (byte/signed byte/word/signed word) 40 [ render::y#4 render::colline#1 ] ( main:2::render:7 [ render::y#4 render::colline#1 ] ) always clobbers reg byte a

View File

@ -557,8 +557,8 @@ Statement [8] (byte*) main::zpptr2#0 ← (const byte*) main::zpptr#0 + (byte) ma
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::j#6 main::j#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::i#4 main::i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::k#2 main::k#1 ]
Potential register analysis [9] main::w#0 ← ((word)) main::j#6 missing fragment vwuz1=_word_vbuxx(main:: vwuz1=(word) main::w#0 vbuxx=(byte) main::j#6 ) allocation: reg byte x [ main::j#6 main::j#1 ] zp ZP_WORD:7 [ main::w#0 ]
Potential register analysis [9] main::w#0 ← ((word)) main::j#6 missing fragment vwuz1=_word_vbuyy(main:: vwuz1=(word) main::w#0 vbuyy=(byte) main::j#6 ) allocation: reg byte y [ main::j#6 main::j#1 ] zp ZP_WORD:7 [ main::w#0 ]
Potential register analysis [9] main::w#0 ← ((word)) main::j#6 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ main::j#6 main::j#1 ] zp ZP_WORD:7 [ main::w#0 ]
Potential register analysis [9] main::w#0 ← ((word)) main::j#6 missing fragment vwuz1=_word_vbuyy allocation: reg byte y [ main::j#6 main::j#1 ] zp ZP_WORD:7 [ main::w#0 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(main:: vwuz1=(word) main::w#0 vbuxx=(byte) main::j#6 )
vwuz1=_word_vbuyy(main:: vwuz1=(word) main::w#0 vbuyy=(byte) main::j#6 )
@ -569,7 +569,7 @@ Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ ma
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:3 [ main::i#4 main::i#1 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:4 [ main::k#2 main::k#1 ]
Statement [8] (byte*) main::zpptr2#0 ← (const byte*) main::zpptr#0 + (byte) main::i#4 [ main::j#6 main::i#4 main::k#2 main::zpptr2#0 ] ( main:2 [ main::j#6 main::i#4 main::k#2 main::zpptr2#0 ] ) always clobbers reg byte a
Potential register analysis [9] main::w#0 ← ((word)) main::j#6 missing fragment vwuz1=_word_vbuxx(main:: vwuz1=(word) main::w#0 vbuxx=(byte) main::j#6 ) allocation: reg byte x [ main::j#6 main::j#1 ] zp ZP_WORD:7 [ main::w#0 ]
Potential register analysis [9] main::w#0 ← ((word)) main::j#6 missing fragment vwuz1=_word_vbuxx allocation: reg byte x [ main::j#6 main::j#1 ] zp ZP_WORD:7 [ main::w#0 ]
MISSING FRAGMENTS
vwuz1=_word_vbuxx(main:: vwuz1=(word) main::w#0 vbuxx=(byte) main::j#6 )
Statement [9] (word) main::w#0 ← ((word)) (byte) main::j#6 [ main::j#6 main::i#4 main::k#2 main::zpptr2#0 main::w#0 ] ( main:2 [ main::j#6 main::i#4 main::k#2 main::zpptr2#0 main::w#0 ] ) always clobbers reg byte a