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

Added a bunch of Z-fragments.

This commit is contained in:
jespergravgaard 2020-08-03 00:27:03 +02:00
parent fe35af0cbe
commit a7359f8395
32 changed files with 241 additions and 139 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1776b64820 1776b6602f
//KICKC FRAGMENT CACHE 17a3d463b0 17a3d47bef
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}
@ -337,22 +337,20 @@ sta {z1}
cmp #{c1}
bcc {la1}
//FRAGMENT pbuz1_derefidx_vbuaa=vbuc1
tay
taz
lda #{c1}
sta ({z1}),y
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuxx=vbuc1
txa
tay
taz
lda #{c1}
sta ({z1}),y
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuyy=vbuc1
lda #{c1}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuzz=vbuc1
tza
tay
lda #{c1}
sta ({z1}),y
sta ({z1}),z
//FRAGMENT vbuaa=_deref_pbuz1
ldy #0
lda ({z1}),y
@ -426,17 +424,9 @@ beq {la1}
ldy {z2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuz2=vbuxx
ldy {z2}
txa
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuz2=vbuyy
tya
ldy {z2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuz2=vbuzz
ldy {z2}
tza
sta ({z1}),y
ldz {z2}
sta ({z1}),z
//FRAGMENT vbuaa=_byte_vwuz1
lda {z1}
//FRAGMENT vbuxx=_byte_vwuz1
@ -2041,9 +2031,17 @@ taz
//FRAGMENT vbuyy_eq_vbuc1_then_la1
cpy #{c1}
beq {la1}
//FRAGMENT pbuz1_derefidx_vbuz2=vbuyy
tya
ldy {z2}
sta ({z1}),y
//FRAGMENT vbuzz_eq_vbuc1_then_la1
cpz #{c1}
beq {la1}
//FRAGMENT pbuz1_derefidx_vbuz2=vbuzz
tza
ldz {z2}
sta ({z1}),z
//FRAGMENT vbuz1_lt_vbuxx_then_la1
cpx {z1}
beq !+

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1776b64820 1776b6602f
//KICKC FRAGMENT CACHE 17a3d463b0 17a3d47bef
//FRAGMENT vduz1=vduc1
lda #<{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1776b64820 1776b6602f
//KICKC FRAGMENT CACHE 17a3d463b0 17a3d47bef
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1776b64820 1776b6602f
//KICKC FRAGMENT CACHE 17a3d463b0 17a3d47bef
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1776b64820 1776b6602f
//KICKC FRAGMENT CACHE 17a3d463b0 17a3d47bef
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}

View File

@ -0,0 +1 @@
sta ({z1}),z

View File

@ -0,0 +1,5 @@
eor ({z1}),z
beq !+
lda #1
!:
eor #1

View File

@ -0,0 +1,2 @@
clc
adc ({z1}),z

View File

@ -0,0 +1 @@
lda ({z1}),z

View File

@ -0,0 +1,3 @@
eor #$ff
sec
adc ({z1}),z

View File

@ -0,0 +1,3 @@
sec
lda ({z1}),z
sbc #{c1}

View File

@ -0,0 +1,3 @@
sec
lda ({z1}),z
sbc {m2}

View File

@ -0,0 +1 @@
and ({z1}),z

View File

@ -0,0 +1 @@
ora ({z1}),z

View File

@ -0,0 +1 @@
eor ({z1}),z

View File

@ -0,0 +1,2 @@
clc
adc ({z1}),z

View File

@ -0,0 +1,2 @@
cmp ({z1}),z
beq {la1}

View File

@ -0,0 +1,6 @@
lda ({z2}),z
sta {m1}
lda #0
sta {m1}+1
sta {m1}+2
sta {m1}+3

View File

@ -0,0 +1,4 @@
lda ({z2}),z
sta {m1}
lda #0
sta {m1}+1

View File

@ -0,0 +1,7 @@
clc
lda {m1}
adc ({z2}),z
sta {m1}
bcc !+
inc {m1}+1
!:

View File

@ -0,0 +1,7 @@
clc
lda {m2}
adc ({z3}),z
sta {m1}
bcc !+
inc {m2}+1
!:

View File

@ -0,0 +1,4 @@
lda ({z2}),z
sta {m1}
lda #0
sta {m1}+1

View File

@ -0,0 +1,6 @@
lda ({z2}),z
asl
sta {m1}
lda #0
rol
sta {m1}+1

View File

@ -1 +1 @@
sta ({z1}),y
sta ({z1}),y

View File

@ -1,5 +1,4 @@
lda ({z2}),y
sta {m1}
iny
lda #0
sta {m1}+1

View File

@ -84,8 +84,8 @@ public class AsmFragmentSystemHash {
}
}
}
// Also hash in all synthesis rules
for(AsmFragmentTemplateSynthesisRule synthesisRule : AsmFragmentTemplateSynthesisRule.getSynthesisRules()) {
// Also hash in all synthesis rules for all CPU's
for(AsmFragmentTemplateSynthesisRule synthesisRule : AsmFragmentTemplateSynthesisRule.getAllSynthesisRules()) {
hashCRLF += synthesisRule.hashCode();
hashLF += synthesisRule.hashCode();
}

View File

@ -1,5 +1,7 @@
package dk.camelot64.kickc.fragment;
import dk.camelot64.kickc.model.TargetCpu;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -182,17 +184,26 @@ class AsmFragmentTemplateSynthesisRule {
return Objects.hash(sigMatch, sigAvoid, asmPrefix, sigReplace, asmPostfix, bindMappings, mapSignature, subDontClobber);
}
/** All the synthesize rules available. */
private static List<AsmFragmentTemplateSynthesisRule> fragmentSyntheses;
/** All the synthesize rules available for each CPU. */
private static Map<TargetCpu, List<AsmFragmentTemplateSynthesisRule>> fragmentSyntheses = new LinkedHashMap<>();
static List<AsmFragmentTemplateSynthesisRule> getSynthesisRules() {
if(fragmentSyntheses == null) {
fragmentSyntheses = initFragmentSyntheses();
static List<AsmFragmentTemplateSynthesisRule> getSynthesisRules(TargetCpu targetCpu) {
if(fragmentSyntheses.get(targetCpu) == null) {
fragmentSyntheses.put(targetCpu, initFragmentSyntheses(targetCpu));
}
return fragmentSyntheses;
return fragmentSyntheses.get(targetCpu);
}
private static List<AsmFragmentTemplateSynthesisRule> initFragmentSyntheses() {
static Collection<AsmFragmentTemplateSynthesisRule> getAllSynthesisRules() {
final LinkedHashSet<AsmFragmentTemplateSynthesisRule> allRules = new LinkedHashSet<>();
for(TargetCpu targetCpu : TargetCpu.values()) {
allRules.addAll(getSynthesisRules(targetCpu));
}
return allRules;
}
private static List<AsmFragmentTemplateSynthesisRule> initFragmentSyntheses(TargetCpu targetCpu) {
// Z1 is replaced by something non-ZP - all above are moved down
Map<String, String> mapZM1 = new LinkedHashMap<>();
mapZM1.put("z2", "z1");
@ -731,6 +742,9 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)c3(.*)", rvalYy+"|"+lvalDerefC3, "ldy {c3}", "$1vb$2yy$3", null, null));
// Rewrite (Z1),y to AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)pb(.)z1_derefidx_vbuyy(.*)_then_(.*)", twoZM1+"|"+rvalAa, "lda ({z1}),y\n" , "$1vb$2aa$3_then_$4", null, mapZM1));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite (Z1),z to AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)pb(.)z1_derefidx_vbuzz(.*)_then_(.*)", twoZM1+"|"+rvalAa, "lda ({z1}),z\n" , "$1vb$2aa$3_then_$4", null, mapZM1));
// Rewrite left-size C1,y to use AA and a STA C1,y
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy=(.*)", null, null, "vb$1aa=$2", "sta {c1},y", null, "yy"));
@ -738,6 +752,9 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy=(.*)", null, "sty $ff\n" , "vb$1aa=$2", "ldy $ff\nsta {c1},y", null));
// Rewrite (Z1),y to save and reload YY from $FF
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuyy=(.*)", twoZM1, "sty $ff\n" , "vb$1aa=$2", "ldy $ff\nsta ({z1}),y", mapZM1));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite (Z1),z to save and reload ZZ from $FF
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuzz=(.*)", twoZM1, "stz $ff\n" , "vb$1aa=$2", "ldz $ff\nsta ({z1}),z", mapZM1));
// Rewrite left-size C1,x to use AA and a STA C1,x
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuxx=(.*)", null, null, "vb$1aa=$2", "sta {c1},x", null, "xx"));
@ -745,11 +762,27 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuxx=(.*)", null, "stx $ff\n" , "vb$1aa=$2", "ldx $ff\nsta {c1},x", null));
// Rewrite (Z1),x to save Y to $FF and reload it into YY
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuxx=(.*)", twoZM1, "stx $ff" , "vb$1aa=$2", "ldy $ff\nsta ({z1}),y", mapZM1));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite (Z1),x to save Y to $FF and reload it into YY
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuxx=(.*)", twoZM1, "stx $ff" , "vb$1aa=$2", "ldz $ff\nsta ({z1}),z", mapZM1));
// TODO: Rewrite (Z1),y assignment to use A
//synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuyy=(.*)", twoZM1+"|"+rvalYy, null , "vb$1aa=$2", "sta ({z1}),y", null, "yy"));
//if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite (Z1),z assignment to use A
// synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuzz=(.*)", twoZM1+"|"+rvalZz, null , "vb$1aa=$2", "sta ({z1}),z", null, "zz"));
// Rewrite (Z1),a to use TAY prefix
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuaa=(.*)", twoZM1+"|"+rvalYy, "tay" , "vb$1aa=$2", "sta ({z1}),y", mapZM1, "yy"));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite (Z1),a to use TAZ prefix
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuaa=(.*)", twoZM1+"|"+rvalZz, "taz" , "vb$1aa=$2", "sta ({z1}),z", mapZM1, "zz"));
// Rewrite (Z1),a to save A to $FF and reload it into YY
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuaa=(.*)", twoZM1, "sta $ff" , "vb$1aa=$2", "ldy $ff\nsta ({z1}),y", mapZM1));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite (Z1),a to save A to $FF and reload it into ZZ
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuaa=(.*)", twoZM1, "sta $ff" , "vb$1aa=$2", "ldz $ff\nsta ({z1}),z", mapZM1));
// Synthesize typed pointer math using void pointers
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)p[^v][^o]([czm][1-9])(.*)", null, null, "$1pvo$2$3", null, null));
@ -790,8 +823,17 @@ class AsmFragmentTemplateSynthesisRule {
// Rewrite trailing right-size (Z1),y to use AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)z1_derefidx_vbuyy", twoZM1+"|"+rvalAa, "lda ({z1}),y", "$1=$2vb$3aa", null, mapZM1, null));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite trailing right-size (Z1),z to use AA
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)z1_derefidx_vbuzz", twoZM1+"|"+rvalAa, "lda ({z1}),z", "$1=$2vb$3aa", null, mapZM1, null));
// Rewrite trailing right-size (Z1),y to use AA - when 2 Z1
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z1(.*)pb(.)z1_derefidx_vbuyy", rvalAa, "lda ({z1}),y", "$1z1$2vb$3aa", null, null, null));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite trailing right-size (Z1),z to use AA - when 2 Z1
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)z1(.*)pb(.)z1_derefidx_vbuzz", rvalAa, "lda ({z1}),z", "$1z1$2vb$3aa", null, null, null));
// TODO: New fragment synth rule creates non-optimal ASM https://gitlab.com/camelot/kickc/-/issues/494
// Rewrite trailing right-size (Z2),y to use AA
// synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)pb(.)z2_derefidx_vbuyy", twoZM2+"|"+rvalAa, "lda ({z2}),y", "$1=$2vb$3aa", null, mapZM2, null));
@ -807,11 +849,15 @@ class AsmFragmentTemplateSynthesisRule {
// Rewrite multiple _derefidx_vbuc1 to use YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuc1(.*)_derefidx_vbuc1(.*)", rvalYy+"|"+ threeC1, "ldy #{c1}", "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", null, mapC1));
if(targetCpu.getCpu65xx().hasRegisterZ())
// Rewrite multiple _derefidx_vbuc1 to use ZZ
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuc1(.*)_derefidx_vbuc1(.*)", rvalZz+"|"+ threeC1, "ldz #{c1}", "$1_derefidx_vbuzz$2_derefidx_vbuzz$3", null, mapC1));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbum1=(.*)", twoZM1+"|"+twoC1, null, "vb$1aa=$2", "ldx {m1}\n" + "sta {c1},x", mapZM1C1));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbum2=(.*)", twoZM1+"|"+twoZM2, null, "vb$1aa=$2", "ldy {m2}\n" + "sta ({z1}),y", mapZM12));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbum1=(.*c1.*)", twoZM1, null, "vb$1aa=$2", "ldx {m1}\n" + "sta {c1},x", mapZM1));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbum1=(.*[mz]1.*)", twoC1, null, "vb$1aa=$2", "ldx {m1}\n" + "sta {c1},x", mapC1));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbum2=(.*)", twoZM1+"|"+twoZM2, null, "vb$1aa=$2", "ldy {m2}\n" + "sta ({z1}),y", mapZM12));
if(targetCpu.getCpu65xx().hasRegisterZ())
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbum2=(.*)", twoZM1+"|"+twoZM2, null, "vb$1aa=$2", "ldz {m2}\n" + "sta ({z1}),z", mapZM12));
// 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... )
@ -839,6 +885,8 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)\\(([vp][bwd][us][mzcaxy][123456axyz])\\)(.*)", null, null, "$1$2$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1_(.*)", rvalYy+"|"+twoZM1, "ldy {z1}", "$1_derefidx_vbuyy_$2", null, mapZM1));
if(targetCpu.getCpu65xx().hasRegisterZ())
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1_(.*)", rvalZz+"|"+twoZM1, "ldz {z1}", "$1_derefidx_vbuzz_$2", null, mapZM1));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_derefidx_vbuz1_(lt|gt|le|ge|eq|neq)_(.*)", rvalXx+"|"+twoZM1, "ldx {z1}", "$1_derefidx_vbuxx_$2_$3", null, mapZM1));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy_(lt|gt|le|ge|eq|neq)_(.*)", rvalAa+"|"+twoC1, "lda {c1},y", "vb$1aa_$2_$3", null, mapC1));
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)c1_derefidx_vbuyy_(lt|gt|le|ge|eq|neq)_(.*c1.*)", rvalAa, "lda {c1},y", "vb$1aa_$2_$3", null, null));

View File

@ -406,7 +406,7 @@ public class AsmFragmentTemplateSynthesizer {
}
}
// Populate with synthesis options
for(AsmFragmentTemplateSynthesisRule rule : AsmFragmentTemplateSynthesisRule.getSynthesisRules()) {
for(AsmFragmentTemplateSynthesisRule rule : AsmFragmentTemplateSynthesisRule.getSynthesisRules(targetCpu)) {
if(rule.matches(signature)) {
AsmFragmentSynthesisOption synthesisOption = new AsmFragmentSynthesisOption(signature, rule);
synthesis.addSynthesisOption(synthesisOption);

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.fragment;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.model.TargetCpu;
import java.io.File;
import java.util.*;
@ -114,19 +115,18 @@ public class AsmFragmentTemplateUsages {
if(logUnusedRules) {
log.append("\nUNUSED ASM FRAGMENT SYNTHESIS RULE ANALYSIS (if found consider removing them)");
Set<AsmFragmentTemplateSynthesisRule> rules =
new LinkedHashSet<>(AsmFragmentTemplateSynthesisRule.getSynthesisRules());
final Collection<AsmFragmentTemplateSynthesisRule> allRules = AsmFragmentTemplateSynthesisRule.getAllSynthesisRules();
for(String signature : signatures) {
Collection<AsmFragmentTemplate> templates =
synthesizer.getBestTemplates(signature, log);
for(AsmFragmentTemplate template : templates) {
while(template.getSynthesis()!=null) {
rules.remove(template.getSynthesis());
allRules.remove(template.getSynthesis());
template = template.getSubFragment();
}
}
}
for(AsmFragmentTemplateSynthesisRule rule : rules) {
for(AsmFragmentTemplateSynthesisRule rule : allRules) {
log.append("Synthesis Rule Unused: - match:" + rule.sigMatch+ " avoid:"+rule.sigAvoid+" replace:"+rule.sigReplace);
}
}

View File

@ -98,10 +98,10 @@ clrscr: {
sta.z line_text
lda #>DEFAULT_SCREEN
sta.z line_text+1
ldz #0
ldx #0
__b1:
// for( char l=0;l<CONIO_HEIGHT; l++ )
cpz #$19
cpx #$19
bcc __b2
// conio_cursor_x = 0
lda #0
@ -121,10 +121,10 @@ clrscr: {
// }
rts
__b2:
ldy #0
ldz #0
__b3:
// for( char c=0;c<CONIO_WIDTH; c++ )
cpy #$28
cpz #$28
bcc __b4
// line_text += CONIO_WIDTH
lda #$28
@ -143,17 +143,17 @@ clrscr: {
inc.z line_cols+1
!:
// for( char l=0;l<CONIO_HEIGHT; l++ )
inz
inx
jmp __b1
__b4:
// line_text[c] = ' '
lda #' '
sta (line_text),y
sta.z (line_text),z
// line_cols[c] = conio_textcolor
lda #LIGHT_BLUE
sta (line_cols),y
sta.z (line_cols),z
// for( char c=0;c<CONIO_WIDTH; c++ )
iny
inz
jmp __b3
}
// Output a NUL-terminated string at the current cursor position

File diff suppressed because one or more lines are too long

View File

@ -108,11 +108,11 @@
(label) clrscr::@5
(label) clrscr::@return
(byte) clrscr::c
(byte) clrscr::c#1 reg byte y 20002.0
(byte) clrscr::c#2 reg byte y 12501.25
(byte) clrscr::c#1 reg byte z 20002.0
(byte) clrscr::c#2 reg byte z 12501.25
(byte) clrscr::l
(byte) clrscr::l#1 reg byte z 2002.0
(byte) clrscr::l#2 reg byte z 333.6666666666667
(byte) clrscr::l#1 reg byte x 2002.0
(byte) clrscr::l#2 reg byte x 333.6666666666667
(byte*) clrscr::line_cols
(byte*) clrscr::line_cols#1 line_cols zp[2]:20 1001.0
(byte*) clrscr::line_cols#5 line_cols zp[2]:20 1500.375
@ -610,8 +610,8 @@ solutions: "
(word) utoa_append::value#1 value zp[2]:20 2.0000002E7
(word) utoa_append::value#2 value zp[2]:20 5018334.166666666
reg byte z [ clrscr::l#2 clrscr::l#1 ]
reg byte y [ clrscr::c#2 clrscr::c#1 ]
reg byte x [ clrscr::l#2 clrscr::l#1 ]
reg byte z [ clrscr::c#2 clrscr::c#1 ]
zp[1]:2 [ queens::row#10 queens::row#1 queens::row#2 legal::row#0 ]
zp[4]:3 [ count#10 count#2 printf_ulong::uvalue#2 printf_ulong::uvalue#0 printf_ulong::uvalue#1 ]
reg byte a [ cputc::c#3 cputc::c#0 cputc::c#2 cputc::c#1 ]