diff --git a/src/main/kc/include/mos6569.h b/src/main/kc/include/mos6569.h new file mode 100644 index 000000000..dbae51e74 --- /dev/null +++ b/src/main/kc/include/mos6569.h @@ -0,0 +1,51 @@ +// MOS 6567 / 6569 Video Interface Chip (VIC II) +// http://archive.6502.org/datasheets/mos_6567_vic_ii_preliminary.pdf +struct MOS6569_VICII { + char SPRITE0_X; + char SPRITE0_Y; + char SPRITE1_X; + char SPRITE1_Y; + char SPRITE2_X; + char SPRITE2_Y; + char SPRITE3_X; + char SPRITE3_Y; + char SPRITE4_X; + char SPRITE4_Y; + char SPRITE5_X; + char SPRITE5_Y; + char SPRITE6_X; + char SPRITE6_Y; + char SPRITE7_X; + char SPRITE7_Y; + char SPRITES_XMSB; + char CONTROL1; + char RASTER; + char LIGHTPEN_X; + char LIGHTPEN_Y; + char SPRITES_ENABLE; + char CONTROL2; + char SPRITES_EXPAND_Y; + char MEMORY; + char IRQ_STATUS; + char IRQ_ENABLE; + char SPRITES_PRIORITY; + char SPRITES_MC; + char SPRITES_EXPAND_X; + char SPRITES_COLLISION; + char SPRITES_BG_COLLISION; + char BORDER_COLOR; + char BG_COLOR; + char BG_COLOR1; + char BG_COLOR2; + char BG_COLOR3; + char SPRITES_MCOLOR1; + char SPRITES_MCOLOR2; + char SPRITE0_COLOR; + char SPRITE1_COLOR; + char SPRITE2_COLOR; + char SPRITE3_COLOR; + char SPRITE4_COLOR; + char SPRITE5_COLOR; + char SPRITE6_COLOR; + char SPRITE7_COLOR; +}; diff --git a/src/test/ref/examples/fire/fire.asm b/src/test/ref/examples/fire/fire.asm index d60eedb4d..47366252e 100644 --- a/src/test/ref/examples/fire/fire.asm +++ b/src/test/ref/examples/fire/fire.asm @@ -168,8 +168,8 @@ fire: { __b2: // buffer[40-1] + buffer[40-1] ldy #$28-1 - clc lda (buffer),y + clc adc (buffer),y // buffer[40-1] + buffer[40-1] + buffer[40] ldy #$28 diff --git a/src/test/ref/examples/fire/fire.log b/src/test/ref/examples/fire/fire.log index 1a332e0f4..04ae16319 100644 --- a/src/test/ref/examples/fire/fire.log +++ b/src/test/ref/examples/fire/fire.log @@ -1881,11 +1881,10 @@ fire: { jmp __b6 // fire::@2 __b2: - // [40] (byte~) fire::$4 ← *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) + *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) -- vbuz1=pbuz2_derefidx_vbuc1_plus_pbuz2_derefidx_vbuc2 + // [40] (byte~) fire::$4 ← *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) + *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) -- vbuz1=pbuz2_derefidx_vbuc1_plus_pbuz2_derefidx_vbuc1 ldy #$28-1 - clc lda (buffer),y - ldy #$28-1 + clc adc (buffer),y sta.z __4 // [41] (byte~) fire::$5 ← (byte~) fire::$4 + *((byte*) fire::buffer#4 + (byte) $28) -- vbuz1=vbuz2_plus_pbuz3_derefidx_vbuc1 @@ -2367,29 +2366,29 @@ Uplift Scope [MOS6581_SID] Uplift Scope [main] Uplift Scope [] -Uplifting [fire] best 147364 combination reg byte a [ fire::c#2 fire::c#0 fire::c#1 ] zp[2]:4 [ fire::buffer#4 fire::buffer#2 ] zp[2]:8 [ fire::buffer#10 fire::buffer#3 ] reg byte a [ fire::sid_rnd1_return#0 ] reg byte a [ fire::$13 ] reg byte a [ fire::$14 ] zp[1]:30 [ fire::$4 ] zp[1]:31 [ fire::$5 ] zp[1]:32 [ fire::$6 ] zp[2]:10 [ fire::screen#10 fire::screen#1 fire::screen#3 ] zp[2]:6 [ fire::screen#4 fire::screen#12 fire::screen#2 ] zp[2]:2 [ fire::screen#0 ] +Uplifting [fire] best 147164 combination reg byte a [ fire::c#2 fire::c#0 fire::c#1 ] zp[2]:4 [ fire::buffer#4 fire::buffer#2 ] zp[2]:8 [ fire::buffer#10 fire::buffer#3 ] reg byte a [ fire::sid_rnd1_return#0 ] reg byte a [ fire::$13 ] reg byte a [ fire::$14 ] zp[1]:30 [ fire::$4 ] zp[1]:31 [ fire::$5 ] zp[1]:32 [ fire::$6 ] zp[2]:10 [ fire::screen#10 fire::screen#1 fire::screen#3 ] zp[2]:6 [ fire::screen#4 fire::screen#12 fire::screen#2 ] zp[2]:2 [ fire::screen#0 ] Limited combination testing to 100 combinations of 16384 possible. -Uplifting [makecharset] best 120964 combination reg byte x [ makecharset::bc#6 makecharset::bc#3 makecharset::bc#7 makecharset::bc#1 makecharset::bc#2 ] reg byte y [ makecharset::b#2 makecharset::b#6 makecharset::b#1 ] zp[1]:20 [ makecharset::ii#2 makecharset::ii#1 ] reg byte a [ makecharset::$11 ] reg byte a [ makecharset::$12 ] zp[1]:43 [ makecharset::$13 ] zp[1]:18 [ makecharset::i#2 makecharset::i#1 ] zp[2]:33 [ makecharset::$17 ] zp[2]:35 [ makecharset::$15 ] zp[2]:37 [ makecharset::$16 ] zp[2]:39 [ makecharset::$18 ] zp[1]:17 [ makecharset::c#2 makecharset::c#1 ] zp[2]:13 [ makecharset::font#2 makecharset::font#1 ] zp[2]:15 [ makecharset::font1#2 makecharset::font1#1 ] +Uplifting [makecharset] best 120764 combination reg byte x [ makecharset::bc#6 makecharset::bc#3 makecharset::bc#7 makecharset::bc#1 makecharset::bc#2 ] reg byte y [ makecharset::b#2 makecharset::b#6 makecharset::b#1 ] zp[1]:20 [ makecharset::ii#2 makecharset::ii#1 ] reg byte a [ makecharset::$11 ] reg byte a [ makecharset::$12 ] zp[1]:43 [ makecharset::$13 ] zp[1]:18 [ makecharset::i#2 makecharset::i#1 ] zp[2]:33 [ makecharset::$17 ] zp[2]:35 [ makecharset::$15 ] zp[2]:37 [ makecharset::$16 ] zp[2]:39 [ makecharset::$18 ] zp[1]:17 [ makecharset::c#2 makecharset::c#1 ] zp[2]:13 [ makecharset::font#2 makecharset::font#1 ] zp[2]:15 [ makecharset::font1#2 makecharset::font1#1 ] Limited combination testing to 100 combinations of 512 possible. -Uplifting [fillscreen] best 120942 combination zp[2]:23 [ fillscreen::screen#5 fillscreen::screen#6 fillscreen::screen#4 ] zp[2]:25 [ fillscreen::i#2 fillscreen::i#1 ] reg byte x [ fillscreen::fill#5 ] -Uplifting [MOS6526_CIA] best 120942 combination -Uplifting [MOS6581_SID] best 120942 combination -Uplifting [main] best 120942 combination -Uplifting [] best 120942 combination +Uplifting [fillscreen] best 120742 combination zp[2]:23 [ fillscreen::screen#5 fillscreen::screen#6 fillscreen::screen#4 ] zp[2]:25 [ fillscreen::i#2 fillscreen::i#1 ] reg byte x [ fillscreen::fill#5 ] +Uplifting [MOS6526_CIA] best 120742 combination +Uplifting [MOS6581_SID] best 120742 combination +Uplifting [main] best 120742 combination +Uplifting [] best 120742 combination Attempting to uplift remaining variables inzp[1]:20 [ makecharset::ii#2 makecharset::ii#1 ] -Uplifting [makecharset] best 120942 combination zp[1]:20 [ makecharset::ii#2 makecharset::ii#1 ] +Uplifting [makecharset] best 120742 combination zp[1]:20 [ makecharset::ii#2 makecharset::ii#1 ] Attempting to uplift remaining variables inzp[1]:30 [ fire::$4 ] -Uplifting [fire] best 120342 combination reg byte a [ fire::$4 ] +Uplifting [fire] best 120142 combination reg byte a [ fire::$4 ] Attempting to uplift remaining variables inzp[1]:31 [ fire::$5 ] -Uplifting [fire] best 119742 combination reg byte a [ fire::$5 ] +Uplifting [fire] best 119542 combination reg byte a [ fire::$5 ] Attempting to uplift remaining variables inzp[1]:32 [ fire::$6 ] -Uplifting [fire] best 119142 combination reg byte a [ fire::$6 ] +Uplifting [fire] best 118942 combination reg byte a [ fire::$6 ] Attempting to uplift remaining variables inzp[1]:43 [ makecharset::$13 ] -Uplifting [makecharset] best 119142 combination zp[1]:43 [ makecharset::$13 ] +Uplifting [makecharset] best 118942 combination zp[1]:43 [ makecharset::$13 ] Attempting to uplift remaining variables inzp[1]:18 [ makecharset::i#2 makecharset::i#1 ] -Uplifting [makecharset] best 119142 combination zp[1]:18 [ makecharset::i#2 makecharset::i#1 ] +Uplifting [makecharset] best 118942 combination zp[1]:18 [ makecharset::i#2 makecharset::i#1 ] Attempting to uplift remaining variables inzp[1]:17 [ makecharset::c#2 makecharset::c#1 ] -Uplifting [makecharset] best 119142 combination zp[1]:17 [ makecharset::c#2 makecharset::c#1 ] +Uplifting [makecharset] best 118942 combination zp[1]:17 [ makecharset::c#2 makecharset::c#1 ] Coalescing zero page register [ zp[2]:2 [ fire::screen#0 ] ] with [ zp[2]:10 [ fire::screen#10 fire::screen#1 fire::screen#3 ] ] - score: 1 Coalescing zero page register [ zp[2]:33 [ makecharset::$17 ] ] with [ zp[2]:35 [ makecharset::$15 ] ] - score: 1 Coalescing zero page register [ zp[2]:37 [ makecharset::$16 ] ] with [ zp[2]:39 [ makecharset::$18 ] ] - score: 1 @@ -2696,11 +2695,10 @@ fire: { jmp __b6 // fire::@2 __b2: - // [40] (byte~) fire::$4 ← *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) + *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) -- vbuaa=pbuz1_derefidx_vbuc1_plus_pbuz1_derefidx_vbuc2 + // [40] (byte~) fire::$4 ← *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) + *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) -- vbuaa=pbuz1_derefidx_vbuc1_plus_pbuz1_derefidx_vbuc1 ldy #$28-1 - clc lda (buffer),y - ldy #$28-1 + clc adc (buffer),y // [41] (byte~) fire::$5 ← (byte~) fire::$4 + *((byte*) fire::buffer#4 + (byte) $28) -- vbuaa=vbuaa_plus_pbuz1_derefidx_vbuc1 ldy #$28 @@ -3063,7 +3061,6 @@ Succesful ASM optimization Pass5NextJumpElimination Removing instruction lda #BLACK Removing instruction ldy #0 Removing instruction ldy #0 -Removing instruction ldy #$28-1 Removing instruction ldy #0 Removing instruction ldy #0 Replacing instruction lda #0 with TXA @@ -3600,10 +3597,10 @@ fire: { // fire::@2 __b2: // buffer[40-1] + buffer[40-1] - // [40] (byte~) fire::$4 ← *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) + *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) -- vbuaa=pbuz1_derefidx_vbuc1_plus_pbuz1_derefidx_vbuc2 + // [40] (byte~) fire::$4 ← *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) + *((byte*) fire::buffer#4 + (byte)(number) $28-(number) 1) -- vbuaa=pbuz1_derefidx_vbuc1_plus_pbuz1_derefidx_vbuc1 ldy #$28-1 - clc lda (buffer),y + clc adc (buffer),y // buffer[40-1] + buffer[40-1] + buffer[40] // [41] (byte~) fire::$5 ← (byte~) fire::$4 + *((byte*) fire::buffer#4 + (byte) $28) -- vbuaa=vbuaa_plus_pbuz1_derefidx_vbuc1 diff --git a/src/test/ref/incrementinarray.asm b/src/test/ref/incrementinarray.asm index 71a34c53b..1a1e5795f 100644 --- a/src/test/ref/incrementinarray.asm +++ b/src/test/ref/incrementinarray.asm @@ -21,10 +21,7 @@ main: { // print_ln() jsr print_ln // txt[1]++; - lda txt+1 - clc - adc #1 - sta txt+1 + inc txt+1 // for ( byte i: 0..10) inx cpx #$b diff --git a/src/test/ref/incrementinarray.log b/src/test/ref/incrementinarray.log index 2f1145b73..ce6ec0eae 100644 --- a/src/test/ref/incrementinarray.log +++ b/src/test/ref/incrementinarray.log @@ -771,11 +771,8 @@ main: { jmp __b3 // main::@3 __b3: - // [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc2 - lda txt+1 - clc - adc #1 - sta txt+1 + // [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc1 + inc txt+1 // [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 inc.z i // [12] if((byte) main::i#1!=(byte) $b) goto main::@4 -- vbuz1_neq_vbuc1_then_la1 @@ -966,9 +963,8 @@ memset: { .byte 0 REGISTER UPLIFT POTENTIAL REGISTERS -Statement [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) [ main::i#2 print_line_cursor#1 ] ( main:2 [ main::i#2 print_line_cursor#1 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Statement [14] (byte*) print_char_cursor#35 ← (byte*) print_line_cursor#1 [ print_char_cursor#35 print_line_cursor#1 main::i#1 ] ( main:2 [ print_char_cursor#35 print_line_cursor#1 main::i#1 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Statement [17] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 [ print_line_cursor#1 print_char_cursor#15 ] ( main:2::print_ln:9 [ main::i#2 print_line_cursor#1 print_char_cursor#15 ] { } ) always clobbers reg byte a Statement [18] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#15) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#15 ] ( main:2::print_ln:9 [ main::i#2 print_line_cursor#1 print_char_cursor#15 ] { } ) always clobbers reg byte a Statement [22] if((byte) 0!=*((byte*) print_str::str#2)) goto print_str::@2 [ print_char_cursor#15 print_str::str#2 ] ( main:2::print_str:7 [ print_line_cursor#19 main::i#2 print_char_cursor#15 print_str::str#2 ] { } ) always clobbers reg byte a reg byte y @@ -977,7 +973,6 @@ Statement [24] (byte) print_char::ch#0 ← *((byte*) print_str::str#2) [ print_c Statement [27] *((byte*) print_char_cursor#15) ← (byte) print_char::ch#0 [ print_char_cursor#15 ] ( main:2::print_str:7::print_char:25 [ print_line_cursor#19 main::i#2 print_str::str#2 print_char_cursor#15 ] { } ) always clobbers reg byte y Statement [35] if((byte*) memset::dst#2!=(const byte*) memset::end#0) goto memset::@2 [ memset::dst#2 ] ( main:2::print_cls:5::memset:31 [ memset::dst#2 ] { } ) always clobbers reg byte a Statement [37] *((byte*) memset::dst#2) ← (const byte) memset::c#0 [ memset::dst#2 ] ( main:2::print_cls:5::memset:31 [ memset::dst#2 ] { } ) always clobbers reg byte a reg byte y -Statement [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) [ main::i#2 print_line_cursor#1 ] ( main:2 [ main::i#2 print_line_cursor#1 ] { } ) always clobbers reg byte a Statement [14] (byte*) print_char_cursor#35 ← (byte*) print_line_cursor#1 [ print_char_cursor#35 print_line_cursor#1 main::i#1 ] ( main:2 [ print_char_cursor#35 print_line_cursor#1 main::i#1 ] { } ) always clobbers reg byte a Statement [17] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 [ print_line_cursor#1 print_char_cursor#15 ] ( main:2::print_ln:9 [ main::i#2 print_line_cursor#1 print_char_cursor#15 ] { } ) always clobbers reg byte a Statement [18] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#15) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#15 ] ( main:2::print_ln:9 [ main::i#2 print_line_cursor#1 print_char_cursor#15 ] { } ) always clobbers reg byte a @@ -1003,14 +998,14 @@ Uplift Scope [RADIX] Uplift Scope [print_ln] Uplift Scope [print_cls] -Uplifting [print_char] best 11701 combination reg byte a [ print_char::ch#0 ] -Uplifting [] best 11701 combination zp[2]:7 [ print_char_cursor#15 print_char_cursor#30 print_char_cursor#35 print_char_cursor#19 ] zp[2]:3 [ print_line_cursor#9 print_line_cursor#19 print_line_cursor#1 ] -Uplifting [print_str] best 11701 combination zp[2]:5 [ print_str::str#2 print_str::str#0 ] -Uplifting [memset] best 11701 combination zp[2]:9 [ memset::dst#2 memset::dst#1 ] -Uplifting [main] best 11611 combination reg byte x [ main::i#2 main::i#1 ] -Uplifting [RADIX] best 11611 combination -Uplifting [print_ln] best 11611 combination -Uplifting [print_cls] best 11611 combination +Uplifting [print_char] best 11641 combination reg byte a [ print_char::ch#0 ] +Uplifting [] best 11641 combination zp[2]:7 [ print_char_cursor#15 print_char_cursor#30 print_char_cursor#35 print_char_cursor#19 ] zp[2]:3 [ print_line_cursor#9 print_line_cursor#19 print_line_cursor#1 ] +Uplifting [print_str] best 11641 combination zp[2]:5 [ print_str::str#2 print_str::str#0 ] +Uplifting [memset] best 11641 combination zp[2]:9 [ memset::dst#2 memset::dst#1 ] +Uplifting [main] best 11551 combination reg byte x [ main::i#2 main::i#1 ] +Uplifting [RADIX] best 11551 combination +Uplifting [print_ln] best 11551 combination +Uplifting [print_cls] best 11551 combination Coalescing zero page register [ zp[2]:9 [ memset::dst#2 memset::dst#1 ] ] with [ zp[2]:5 [ print_str::str#2 print_str::str#0 ] ] Allocated (was zp[2]:3) zp[2]:2 [ print_line_cursor#9 print_line_cursor#19 print_line_cursor#1 ] Allocated (was zp[2]:7) zp[2]:4 [ print_char_cursor#15 print_char_cursor#30 print_char_cursor#35 print_char_cursor#19 ] @@ -1080,11 +1075,8 @@ main: { jmp __b3 // main::@3 __b3: - // [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc2 - lda txt+1 - clc - adc #1 - sta txt+1 + // [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc1 + inc txt+1 // [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx inx // [12] if((byte) main::i#1!=(byte) $b) goto main::@4 -- vbuxx_neq_vbuc1_then_la1 @@ -1394,7 +1386,7 @@ reg byte a [ print_char::ch#0 ] FINAL ASSEMBLER -Score: 9940 +Score: 9880 // File Comments // Upstart @@ -1444,11 +1436,8 @@ main: { jsr print_ln // main::@3 // txt[1]++; - // [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc2 - lda txt+1 - clc - adc #1 - sta txt+1 + // [10] *((const byte*) txt+(byte) 1) ← ++ *((const byte*) txt+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc1 + inc txt+1 // for ( byte i: 0..10) // [11] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx inx diff --git a/src/test/ref/linegen.asm b/src/test/ref/linegen.asm index 510f234b3..626ae0340 100644 --- a/src/test/ref/linegen.asm +++ b/src/test/ref/linegen.asm @@ -377,10 +377,6 @@ lin16u_gen: { sbc.z min+1 sta.z ampl+1 // divr16u(ampl, length-1, 0) - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 lda #<0 sta.z divr16u.rem sta.z divr16u.rem+1 @@ -392,10 +388,6 @@ lin16u_gen: { lda.z divr16u.return+1 sta.z stepi+1 // divr16u(0, length-1, rem16u) - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 lda #<0 sta.z divr16u.dividend sta.z divr16u.dividend+1 @@ -480,13 +472,12 @@ lin16u_gen: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zp(7) dividend, word zp($1d) divisor, word zp($13) rem) +// divr16u(word zp(7) dividend, word zp($13) rem) divr16u: { .label rem = $13 .label dividend = 7 .label quotient = $15 .label return = $15 - .label divisor = $1d ldx #0 txa sta.z quotient @@ -515,11 +506,11 @@ divr16u: { rol.z quotient+1 // if(rem>=divisor) lda.z rem+1 - cmp.z divisor+1 + cmp #>$14-1 bcc __b3 bne !+ lda.z rem - cmp.z divisor + cmp #<$14-1 bcc __b3 !: // quotient++; @@ -530,10 +521,10 @@ divr16u: { // rem = rem - divisor lda.z rem sec - sbc.z divisor + sbc #<$14-1 sta.z rem lda.z rem+1 - sbc.z divisor+1 + sbc #>$14-1 sta.z rem+1 __b3: // for( char i : 0..15) diff --git a/src/test/ref/linegen.cfg b/src/test/ref/linegen.cfg index 80c3750b8..8e2e315b1 100644 --- a/src/test/ref/linegen.cfg +++ b/src/test/ref/linegen.cfg @@ -269,7 +269,6 @@ lin16u_gen::@2: scope:[lin16u_gen] from lin16u_gen::@1 (word()) divr16u((word) divr16u::dividend , (word) divr16u::divisor , (word) divr16u::rem) divr16u: scope:[divr16u] from lin16u_gen lin16u_gen::@3 - [123] (word) divr16u::divisor#6 ← phi( lin16u_gen/(byte) $14-(byte) 1 lin16u_gen::@3/(byte) $14-(byte) 1 ) [123] (word) divr16u::dividend#5 ← phi( lin16u_gen/(word) divr16u::dividend#1 lin16u_gen::@3/(byte) 0 ) [123] (word) divr16u::rem#10 ← phi( lin16u_gen/(byte) 0 lin16u_gen::@3/(word) divr16u::rem#4 ) to:divr16u::@1 @@ -290,11 +289,11 @@ divr16u::@2: scope:[divr16u] from divr16u::@1 divr16u::@4 [130] (word) divr16u::rem#6 ← phi( divr16u::@1/(word) divr16u::rem#0 divr16u::@4/(word) divr16u::rem#1 ) [131] (word) divr16u::dividend#0 ← (word) divr16u::dividend#3 << (byte) 1 [132] (word) divr16u::quotient#1 ← (word) divr16u::quotient#3 << (byte) 1 - [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 + [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 to:divr16u::@5 divr16u::@5: scope:[divr16u] from divr16u::@2 [134] (word) divr16u::quotient#2 ← ++ (word) divr16u::quotient#1 - [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 + [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 to:divr16u::@3 divr16u::@3: scope:[divr16u] from divr16u::@2 divr16u::@5 [136] (word) divr16u::return#0 ← phi( divr16u::@2/(word) divr16u::quotient#1 divr16u::@5/(word) divr16u::quotient#2 ) diff --git a/src/test/ref/linegen.log b/src/test/ref/linegen.log index 850b09e7a..922e4cb41 100644 --- a/src/test/ref/linegen.log +++ b/src/test/ref/linegen.log @@ -1654,6 +1654,8 @@ Inlining constant with var siblings (const word) divr16u::divisor#1 Constant inlined divr16u::divisor#1 = (byte) $14-(byte) 1 Constant inlined divr16u::divisor#0 = (byte) $14-(byte) 1 Successful SSA optimization Pass2ConstantInlining +Identical Phi Values (word) divr16u::divisor#6 (byte) $14-(byte) 1 +Successful SSA optimization Pass2IdenticalPhiElimination Added new block during phi lifting divr16u::@7(between divr16u::@3 and divr16u::@1) Added new block during phi lifting divr16u::@8(between divr16u::@1 and divr16u::@2) Added new block during phi lifting divr16u::@9(between divr16u::@2 and divr16u::@3) @@ -1695,7 +1697,7 @@ Calls in [print_str] to print_char:119 Calls in [print_cls] to memset:124 Calls in [lin16u_gen] to divr16u:140 divr16u:145 -Created 29 initial phi equivalence classes +Created 28 initial phi equivalence classes Coalesced [19] print_char_cursor#99 ← print_char_cursor#11 Coalesced (already) [23] print_char_cursor#92 ← print_char_cursor#11 Not coalescing [32] print_char_cursor#98 ← print_line_cursor#1 @@ -1748,7 +1750,7 @@ Coalesced [189] divr16u::i#7 ← divr16u::i#1 Coalesced [190] divr16u::rem#17 ← divr16u::rem#6 Coalesced [191] divr16u::return#7 ← divr16u::quotient#1 Coalesced [192] divr16u::rem#15 ← divr16u::rem#0 -Coalesced down to 18 phi equivalence classes +Coalesced down to 17 phi equivalence classes Culled Empty Block (label) @1 Culled Empty Block (label) @2 Culled Empty Block (label) @4 @@ -2080,7 +2082,6 @@ lin16u_gen::@2: scope:[lin16u_gen] from lin16u_gen::@1 (word()) divr16u((word) divr16u::dividend , (word) divr16u::divisor , (word) divr16u::rem) divr16u: scope:[divr16u] from lin16u_gen lin16u_gen::@3 - [123] (word) divr16u::divisor#6 ← phi( lin16u_gen/(byte) $14-(byte) 1 lin16u_gen::@3/(byte) $14-(byte) 1 ) [123] (word) divr16u::dividend#5 ← phi( lin16u_gen/(word) divr16u::dividend#1 lin16u_gen::@3/(byte) 0 ) [123] (word) divr16u::rem#10 ← phi( lin16u_gen/(byte) 0 lin16u_gen::@3/(word) divr16u::rem#4 ) to:divr16u::@1 @@ -2101,11 +2102,11 @@ divr16u::@2: scope:[divr16u] from divr16u::@1 divr16u::@4 [130] (word) divr16u::rem#6 ← phi( divr16u::@1/(word) divr16u::rem#0 divr16u::@4/(word) divr16u::rem#1 ) [131] (word) divr16u::dividend#0 ← (word) divr16u::dividend#3 << (byte) 1 [132] (word) divr16u::quotient#1 ← (word) divr16u::quotient#3 << (byte) 1 - [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 + [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 to:divr16u::@5 divr16u::@5: scope:[divr16u] from divr16u::@2 [134] (word) divr16u::quotient#2 ← ++ (word) divr16u::quotient#1 - [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 + [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 to:divr16u::@3 divr16u::@3: scope:[divr16u] from divr16u::@2 divr16u::@5 [136] (word) divr16u::return#0 ← phi( divr16u::@2/(word) divr16u::quotient#1 divr16u::@5/(word) divr16u::quotient#2 ) @@ -2131,7 +2132,6 @@ VARIABLE REGISTER WEIGHTS (word) divr16u::dividend#3 4429.142857142857 (word) divr16u::dividend#5 1102.0 (word) divr16u::divisor -(word) divr16u::divisor#6 1250.125 (byte) divr16u::i (byte) divr16u::i#1 15001.5 (byte) divr16u::i#2 1538.6153846153845 @@ -2251,7 +2251,6 @@ Initial phi equivalence classes [ lin16u_gen::i#2 lin16u_gen::i#1 ] [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] -[ divr16u::divisor#6 ] [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] @@ -2285,7 +2284,6 @@ Complete equivalence classes [ lin16u_gen::i#2 lin16u_gen::i#1 ] [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] -[ divr16u::divisor#6 ] [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] @@ -2318,26 +2316,25 @@ Allocated zp[2]:17 [ lin16u_gen::min#3 ] Allocated zp[2]:19 [ lin16u_gen::i#2 lin16u_gen::i#1 ] Allocated zp[4]:21 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] Allocated zp[2]:25 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] -Allocated zp[2]:27 [ divr16u::divisor#6 ] -Allocated zp[2]:29 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] -Allocated zp[2]:31 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] -Allocated zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] -Allocated zp[1]:35 [ divr16u::i#2 divr16u::i#1 ] -Allocated zp[1]:36 [ main::$27 ] -Allocated zp[1]:37 [ main::$28 ] -Allocated zp[1]:38 [ main::$29 ] -Allocated zp[1]:39 [ print_uchar::$0 ] -Allocated zp[1]:40 [ print_uchar::$2 ] -Allocated zp[2]:41 [ lin16u_gen::ampl#0 ] -Allocated zp[2]:43 [ divr16u::return#2 ] -Allocated zp[2]:45 [ lin16u_gen::stepi#0 ] -Allocated zp[2]:47 [ divr16u::return#3 ] -Allocated zp[2]:49 [ lin16u_gen::stepf#0 ] -Allocated zp[4]:51 [ lin16u_gen::step#0 ] -Allocated zp[2]:55 [ lin16u_gen::$6 ] -Allocated zp[1]:57 [ divr16u::$1 ] -Allocated zp[1]:58 [ divr16u::$2 ] -Allocated zp[2]:59 [ rem16u#1 ] +Allocated zp[2]:27 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] +Allocated zp[2]:29 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] +Allocated zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] +Allocated zp[1]:33 [ divr16u::i#2 divr16u::i#1 ] +Allocated zp[1]:34 [ main::$27 ] +Allocated zp[1]:35 [ main::$28 ] +Allocated zp[1]:36 [ main::$29 ] +Allocated zp[1]:37 [ print_uchar::$0 ] +Allocated zp[1]:38 [ print_uchar::$2 ] +Allocated zp[2]:39 [ lin16u_gen::ampl#0 ] +Allocated zp[2]:41 [ divr16u::return#2 ] +Allocated zp[2]:43 [ lin16u_gen::stepi#0 ] +Allocated zp[2]:45 [ divr16u::return#3 ] +Allocated zp[2]:47 [ lin16u_gen::stepf#0 ] +Allocated zp[4]:49 [ lin16u_gen::step#0 ] +Allocated zp[2]:53 [ lin16u_gen::$6 ] +Allocated zp[1]:55 [ divr16u::$1 ] +Allocated zp[1]:56 [ divr16u::$2 ] +Allocated zp[2]:57 [ rem16u#1 ] INITIAL ASM Target platform is c64basic / MOS6502X @@ -2351,7 +2348,7 @@ Target platform is c64basic / MOS6502X // Global Constants & labels .const SIZEOF_WORD = 2 // Remainder after unsigned 16-bit division - .label rem16u = $3b + .label rem16u = $39 .label print_char_cursor = 9 .label print_line_cursor = 3 // @begin @@ -2372,9 +2369,9 @@ __bend_from___b1: __bend: // main main: { - .label __27 = $24 - .label __28 = $25 - .label __29 = $26 + .label __27 = $22 + .label __28 = $23 + .label __29 = $24 .label i = 2 // [5] call lin16u_gen // [103] phi from main to lin16u_gen [phi:main->lin16u_gen] @@ -2885,8 +2882,8 @@ print_uint: { // Print a char as HEX // print_uchar(byte zp(7) b) print_uchar: { - .label __0 = $27 - .label __2 = $28 + .label __0 = $25 + .label __2 = $26 .label b = 7 // [76] (byte~) print_uchar::$0 ← (byte) print_uchar::b#3 >> (byte) 4 -- vbuz1=vbuz2_ror_4 lda.z b @@ -3059,11 +3056,11 @@ memset: { // length - the number of points in a total sinus wavelength (the size of the table) // lin16u_gen(word zp($11) min, word zp($f) max, word* zp($19) lintab) lin16u_gen: { - .label __6 = $37 - .label ampl = $29 - .label stepi = $2d - .label stepf = $31 - .label step = $33 + .label __6 = $35 + .label ampl = $27 + .label stepi = $2b + .label stepf = $2f + .label step = $31 .label val = $15 .label lintab = $19 .label i = $13 @@ -3085,13 +3082,8 @@ lin16u_gen: { // [106] call divr16u // [123] phi from lin16u_gen to divr16u [phi:lin16u_gen->divr16u] divr16u_from_lin16u_gen: - // [123] phi (word) divr16u::divisor#6 = (byte) $14-(byte) 1 [phi:lin16u_gen->divr16u#0] -- vwuz1=vbuc1 - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 - // [123] phi (word) divr16u::dividend#5 = (word) divr16u::dividend#1 [phi:lin16u_gen->divr16u#1] -- register_copy - // [123] phi (word) divr16u::rem#10 = (byte) 0 [phi:lin16u_gen->divr16u#2] -- vwuz1=vbuc1 + // [123] phi (word) divr16u::dividend#5 = (word) divr16u::dividend#1 [phi:lin16u_gen->divr16u#0] -- register_copy + // [123] phi (word) divr16u::rem#10 = (byte) 0 [phi:lin16u_gen->divr16u#1] -- vwuz1=vbuc1 lda #<0 sta.z divr16u.rem lda #>0 @@ -3118,17 +3110,12 @@ lin16u_gen: { // [110] call divr16u // [123] phi from lin16u_gen::@3 to divr16u [phi:lin16u_gen::@3->divr16u] divr16u_from___b3: - // [123] phi (word) divr16u::divisor#6 = (byte) $14-(byte) 1 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 - // [123] phi (word) divr16u::dividend#5 = (byte) 0 [phi:lin16u_gen::@3->divr16u#1] -- vwuz1=vbuc1 + // [123] phi (word) divr16u::dividend#5 = (byte) 0 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 lda #<0 sta.z divr16u.dividend lda #>0 sta.z divr16u.dividend+1 - // [123] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#2] -- register_copy + // [123] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#1] -- register_copy jsr divr16u // [111] (word) divr16u::return#3 ← (word) divr16u::return#0 -- vwuz1=vwuz2 lda.z divr16u.return @@ -3240,18 +3227,17 @@ lin16u_gen: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zp($1f) dividend, word zp($1b) divisor, word zp($1d) rem) +// divr16u(word zp($1d) dividend, word zp($1b) rem) divr16u: { - .label __1 = $39 - .label __2 = $3a - .label rem = $1d - .label dividend = $1f - .label quotient = $21 - .label i = $23 - .label return = $21 - .label return_1 = $2b - .label return_2 = $2f - .label divisor = $1b + .label __1 = $37 + .label __2 = $38 + .label rem = $1b + .label dividend = $1d + .label quotient = $1f + .label i = $21 + .label return = $1f + .label return_1 = $29 + .label return_2 = $2d // [124] phi from divr16u to divr16u::@1 [phi:divr16u->divr16u::@1] __b1_from_divr16u: // [124] phi (byte) divr16u::i#2 = (byte) 0 [phi:divr16u->divr16u::@1#0] -- vbuz1=vbuc1 @@ -3308,13 +3294,13 @@ divr16u: { // [132] (word) divr16u::quotient#1 ← (word) divr16u::quotient#3 << (byte) 1 -- vwuz1=vwuz1_rol_1 asl.z quotient rol.z quotient+1 - // [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 -- vwuz1_lt_vwuz2_then_la1 + // [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 -- vwuz1_lt_vbuc1_then_la1 lda.z rem+1 - cmp.z divisor+1 + cmp #>$14-1 bcc __b3_from___b2 bne !+ lda.z rem - cmp.z divisor + cmp #<$14-1 bcc __b3_from___b2 !: jmp __b5 @@ -3325,13 +3311,13 @@ divr16u: { bne !+ inc.z quotient+1 !: - // [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 -- vwuz1=vwuz1_minus_vwuz2 + // [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 -- vwuz1=vwuz1_minus_vwuc1 lda.z rem sec - sbc.z divisor + sbc #<$14-1 sta.z rem lda.z rem+1 - sbc.z divisor+1 + sbc #>$14-1 sta.z rem+1 // [136] phi from divr16u::@2 divr16u::@5 to divr16u::@3 [phi:divr16u::@2/divr16u::@5->divr16u::@3] __b3_from___b2: @@ -3400,10 +3386,10 @@ Statement [118] (word~) lin16u_gen::$6 ← > (dword) lin16u_gen::val#2 [ lin16u_ Statement [119] *((word*) lin16u_gen::lintab#4) ← (word~) lin16u_gen::$6 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] ( main:2::lin16u_gen:5 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] { } main:2::lin16u_gen:7 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] { } main:2::lin16u_gen:9 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] { } ) always clobbers reg byte a reg byte y Statement [120] (dword) lin16u_gen::val#1 ← (dword) lin16u_gen::val#2 + (dword) lin16u_gen::step#0 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] ( main:2::lin16u_gen:5 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] { } main:2::lin16u_gen:7 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] { } main:2::lin16u_gen:9 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] { } ) always clobbers reg byte a Statement [121] (word*) lin16u_gen::lintab#3 ← (word*) lin16u_gen::lintab#4 + (const byte) SIZEOF_WORD [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] ( main:2::lin16u_gen:5 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] { } main:2::lin16u_gen:7 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] { } main:2::lin16u_gen:9 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] { } ) always clobbers reg byte a -Statement [129] (word) divr16u::rem#1 ← (word) divr16u::rem#0 | (byte) 1 [ divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:35 [ divr16u::i#2 divr16u::i#1 ] -Statement [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 [ divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a -Statement [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 [ divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a +Statement [129] (word) divr16u::rem#1 ← (word) divr16u::rem#0 | (byte) 1 [ divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:33 [ divr16u::i#2 divr16u::i#1 ] +Statement [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 [ divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a +Statement [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 [ divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a Statement [139] (word) rem16u#1 ← (word) divr16u::rem#11 [ divr16u::return#0 rem16u#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::return#0 rem16u#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::return#0 rem16u#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::return#0 rem16u#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::return#0 rem16u#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::return#0 rem16u#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::return#0 rem16u#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a Statement [28] (byte*) print_char_cursor#98 ← (byte*) print_line_cursor#1 [ print_char_cursor#98 print_line_cursor#1 ] ( main:2 [ print_char_cursor#98 print_line_cursor#1 ] { { print_char_cursor#87 = print_char_cursor#98 } } ) always clobbers reg byte a Statement [44] (byte*) print_char_cursor#102 ← (byte*) print_line_cursor#1 [ main::i#10 print_line_cursor#1 print_uchar::b#2 print_char_cursor#102 ] ( main:2 [ main::i#10 print_line_cursor#1 print_uchar::b#2 print_char_cursor#102 ] { { print_uchar::b#2 = print_uchar::b#3 main::i#10 } { print_char_cursor#102 = print_char_cursor#82 } } ) always clobbers reg byte a @@ -3436,9 +3422,9 @@ Statement [118] (word~) lin16u_gen::$6 ← > (dword) lin16u_gen::val#2 [ lin16u_ Statement [119] *((word*) lin16u_gen::lintab#4) ← (word~) lin16u_gen::$6 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] ( main:2::lin16u_gen:5 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] { } main:2::lin16u_gen:7 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] { } main:2::lin16u_gen:9 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#2 lin16u_gen::lintab#4 ] { } ) always clobbers reg byte a reg byte y Statement [120] (dword) lin16u_gen::val#1 ← (dword) lin16u_gen::val#2 + (dword) lin16u_gen::step#0 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] ( main:2::lin16u_gen:5 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] { } main:2::lin16u_gen:7 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] { } main:2::lin16u_gen:9 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::lintab#4 lin16u_gen::val#1 ] { } ) always clobbers reg byte a Statement [121] (word*) lin16u_gen::lintab#3 ← (word*) lin16u_gen::lintab#4 + (const byte) SIZEOF_WORD [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] ( main:2::lin16u_gen:5 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] { } main:2::lin16u_gen:7 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] { } main:2::lin16u_gen:9 [ lin16u_gen::step#0 lin16u_gen::i#2 lin16u_gen::val#1 lin16u_gen::lintab#3 ] { } ) always clobbers reg byte a -Statement [129] (word) divr16u::rem#1 ← (word) divr16u::rem#0 | (byte) 1 [ divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a -Statement [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 [ divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a -Statement [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 [ divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::divisor#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a +Statement [129] (word) divr16u::rem#1 ← (word) divr16u::rem#0 | (byte) 1 [ divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::dividend#3 divr16u::quotient#3 divr16u::i#2 divr16u::rem#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a +Statement [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 [ divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::rem#6 divr16u::quotient#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a +Statement [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 [ divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::i#2 divr16u::dividend#0 divr16u::quotient#2 divr16u::rem#2 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a Statement [139] (word) rem16u#1 ← (word) divr16u::rem#11 [ divr16u::return#0 rem16u#1 ] ( main:2::lin16u_gen:5::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::return#0 rem16u#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:7::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::return#0 rem16u#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:9::divr16u:106 [ lin16u_gen::min#3 lin16u_gen::lintab#6 divr16u::return#0 rem16u#1 ] { { divr16u::dividend#1 = divr16u::dividend#5 lin16u_gen::ampl#0 } { divr16u::return#0 = divr16u::return#2 } } main:2::lin16u_gen:5::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::return#0 rem16u#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:7::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::return#0 rem16u#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } main:2::lin16u_gen:9::divr16u:110 [ lin16u_gen::min#3 lin16u_gen::lintab#6 lin16u_gen::stepi#0 divr16u::return#0 rem16u#1 ] { { divr16u::rem#10 = divr16u::rem#4 rem16u#1 } { divr16u::return#0 = divr16u::return#3 } } ) always clobbers reg byte a Potential registers zp[1]:2 [ main::i#10 main::i#1 ] : zp[1]:2 , reg byte x , Potential registers zp[2]:3 [ print_line_cursor#11 print_line_cursor#21 print_line_cursor#1 ] : zp[2]:3 , @@ -3453,65 +3439,63 @@ Potential registers zp[2]:17 [ lin16u_gen::min#3 ] : zp[2]:17 , Potential registers zp[2]:19 [ lin16u_gen::i#2 lin16u_gen::i#1 ] : zp[2]:19 , Potential registers zp[4]:21 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] : zp[4]:21 , Potential registers zp[2]:25 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] : zp[2]:25 , -Potential registers zp[2]:27 [ divr16u::divisor#6 ] : zp[2]:27 , -Potential registers zp[2]:29 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] : zp[2]:29 , -Potential registers zp[2]:31 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] : zp[2]:31 , -Potential registers zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] : zp[2]:33 , -Potential registers zp[1]:35 [ divr16u::i#2 divr16u::i#1 ] : zp[1]:35 , reg byte x , reg byte y , -Potential registers zp[1]:36 [ main::$27 ] : zp[1]:36 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:37 [ main::$28 ] : zp[1]:37 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:38 [ main::$29 ] : zp[1]:38 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:39 [ print_uchar::$0 ] : zp[1]:39 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:40 [ print_uchar::$2 ] : zp[1]:40 , reg byte a , reg byte x , reg byte y , -Potential registers zp[2]:41 [ lin16u_gen::ampl#0 ] : zp[2]:41 , -Potential registers zp[2]:43 [ divr16u::return#2 ] : zp[2]:43 , -Potential registers zp[2]:45 [ lin16u_gen::stepi#0 ] : zp[2]:45 , -Potential registers zp[2]:47 [ divr16u::return#3 ] : zp[2]:47 , -Potential registers zp[2]:49 [ lin16u_gen::stepf#0 ] : zp[2]:49 , -Potential registers zp[4]:51 [ lin16u_gen::step#0 ] : zp[4]:51 , -Potential registers zp[2]:55 [ lin16u_gen::$6 ] : zp[2]:55 , -Potential registers zp[1]:57 [ divr16u::$1 ] : zp[1]:57 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:58 [ divr16u::$2 ] : zp[1]:58 , reg byte a , reg byte x , reg byte y , -Potential registers zp[2]:59 [ rem16u#1 ] : zp[2]:59 , +Potential registers zp[2]:27 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] : zp[2]:27 , +Potential registers zp[2]:29 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] : zp[2]:29 , +Potential registers zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] : zp[2]:31 , +Potential registers zp[1]:33 [ divr16u::i#2 divr16u::i#1 ] : zp[1]:33 , reg byte x , reg byte y , +Potential registers zp[1]:34 [ main::$27 ] : zp[1]:34 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:35 [ main::$28 ] : zp[1]:35 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:36 [ main::$29 ] : zp[1]:36 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:37 [ print_uchar::$0 ] : zp[1]:37 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:38 [ print_uchar::$2 ] : zp[1]:38 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:39 [ lin16u_gen::ampl#0 ] : zp[2]:39 , +Potential registers zp[2]:41 [ divr16u::return#2 ] : zp[2]:41 , +Potential registers zp[2]:43 [ lin16u_gen::stepi#0 ] : zp[2]:43 , +Potential registers zp[2]:45 [ divr16u::return#3 ] : zp[2]:45 , +Potential registers zp[2]:47 [ lin16u_gen::stepf#0 ] : zp[2]:47 , +Potential registers zp[4]:49 [ lin16u_gen::step#0 ] : zp[4]:49 , +Potential registers zp[2]:53 [ lin16u_gen::$6 ] : zp[2]:53 , +Potential registers zp[1]:55 [ divr16u::$1 ] : zp[1]:55 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:56 [ divr16u::$2 ] : zp[1]:56 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:57 [ rem16u#1 ] : zp[2]:57 , REGISTER UPLIFT SCOPES Uplift Scope [print_char] 1,360,010: zp[1]:8 [ print_char::ch#3 print_char::ch#0 print_char::ch#1 print_char::ch#2 ] -Uplift Scope [] 1,105,841.04: zp[2]:9 [ print_char_cursor#87 print_char_cursor#50 print_char_cursor#82 print_char_cursor#102 print_char_cursor#2 print_char_cursor#11 print_char_cursor#98 ] 209,621.67: zp[2]:3 [ print_line_cursor#11 print_line_cursor#21 print_line_cursor#1 ] 220.4: zp[2]:59 [ rem16u#1 ] +Uplift Scope [] 1,105,841.04: zp[2]:9 [ print_char_cursor#87 print_char_cursor#50 print_char_cursor#82 print_char_cursor#102 print_char_cursor#2 print_char_cursor#11 print_char_cursor#98 ] 209,621.67: zp[2]:3 [ print_line_cursor#11 print_line_cursor#21 print_line_cursor#1 ] 220.4: zp[2]:57 [ rem16u#1 ] Uplift Scope [print_str] 301,254.25: zp[2]:11 [ print_str::str#10 print_str::str#13 print_str::str#0 ] -Uplift Scope [divr16u] 90,147.42: zp[2]:29 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] 31,817.75: zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] 20,002: zp[1]:57 [ divr16u::$1 ] 20,002: zp[1]:58 [ divr16u::$2 ] 16,540.12: zp[1]:35 [ divr16u::i#2 divr16u::i#1 ] 8,233.39: zp[2]:31 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] 1,250.12: zp[2]:27 [ divr16u::divisor#6 ] 202: zp[2]:43 [ divr16u::return#2 ] 202: zp[2]:47 [ divr16u::return#3 ] -Uplift Scope [print_uchar] 20,002: zp[1]:39 [ print_uchar::$0 ] 20,002: zp[1]:40 [ print_uchar::$2 ] 9,631.25: zp[1]:7 [ print_uchar::b#3 print_uchar::b#2 print_uchar::b#0 print_uchar::b#1 ] +Uplift Scope [divr16u] 90,147.42: zp[2]:27 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] 31,817.75: zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] 20,002: zp[1]:55 [ divr16u::$1 ] 20,002: zp[1]:56 [ divr16u::$2 ] 16,540.12: zp[1]:33 [ divr16u::i#2 divr16u::i#1 ] 8,233.39: zp[2]:29 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] 202: zp[2]:41 [ divr16u::return#2 ] 202: zp[2]:45 [ divr16u::return#3 ] +Uplift Scope [print_uchar] 20,002: zp[1]:37 [ print_uchar::$0 ] 20,002: zp[1]:38 [ print_uchar::$2 ] 9,631.25: zp[1]:7 [ print_uchar::b#3 print_uchar::b#2 print_uchar::b#0 print_uchar::b#1 ] Uplift Scope [memset] 33,336.67: zp[2]:13 [ memset::dst#2 memset::dst#1 ] -Uplift Scope [lin16u_gen] 2,502.5: zp[2]:19 [ lin16u_gen::i#2 lin16u_gen::i#1 ] 2,002: zp[2]:55 [ lin16u_gen::$6 ] 1,645.33: zp[4]:21 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] 1,630.22: zp[2]:25 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] 202: zp[2]:41 [ lin16u_gen::ampl#0 ] 202: zp[2]:49 [ lin16u_gen::stepf#0 ] 122.44: zp[4]:51 [ lin16u_gen::step#0 ] 101: zp[2]:15 [ lin16u_gen::max#3 ] 40.4: zp[2]:45 [ lin16u_gen::stepi#0 ] 18.36: zp[2]:17 [ lin16u_gen::min#3 ] +Uplift Scope [lin16u_gen] 2,502.5: zp[2]:19 [ lin16u_gen::i#2 lin16u_gen::i#1 ] 2,002: zp[2]:53 [ lin16u_gen::$6 ] 1,645.33: zp[4]:21 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] 1,630.22: zp[2]:25 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] 202: zp[2]:39 [ lin16u_gen::ampl#0 ] 202: zp[2]:47 [ lin16u_gen::stepf#0 ] 122.44: zp[4]:49 [ lin16u_gen::step#0 ] 101: zp[2]:15 [ lin16u_gen::max#3 ] 40.4: zp[2]:43 [ lin16u_gen::stepi#0 ] 18.36: zp[2]:17 [ lin16u_gen::min#3 ] Uplift Scope [print_uint] 1,374.33: zp[2]:5 [ print_uint::w#10 print_uint::w#3 print_uint::w#4 print_uint::w#5 ] -Uplift Scope [main] 234.14: zp[1]:2 [ main::i#10 main::i#1 ] 202: zp[1]:36 [ main::$27 ] 202: zp[1]:37 [ main::$28 ] 202: zp[1]:38 [ main::$29 ] +Uplift Scope [main] 234.14: zp[1]:2 [ main::i#10 main::i#1 ] 202: zp[1]:34 [ main::$27 ] 202: zp[1]:35 [ main::$28 ] 202: zp[1]:36 [ main::$29 ] Uplift Scope [RADIX] Uplift Scope [print_ln] Uplift Scope [print_cls] -Uplifting [print_char] best 14194 combination reg byte a [ print_char::ch#3 print_char::ch#0 print_char::ch#1 print_char::ch#2 ] -Uplifting [] best 14194 combination zp[2]:9 [ print_char_cursor#87 print_char_cursor#50 print_char_cursor#82 print_char_cursor#102 print_char_cursor#2 print_char_cursor#11 print_char_cursor#98 ] zp[2]:3 [ print_line_cursor#11 print_line_cursor#21 print_line_cursor#1 ] zp[2]:59 [ rem16u#1 ] -Uplifting [print_str] best 14194 combination zp[2]:11 [ print_str::str#10 print_str::str#13 print_str::str#0 ] -Uplifting [divr16u] best 13984 combination zp[2]:29 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] reg byte a [ divr16u::$1 ] reg byte a [ divr16u::$2 ] reg byte x [ divr16u::i#2 divr16u::i#1 ] zp[2]:31 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] zp[2]:27 [ divr16u::divisor#6 ] zp[2]:43 [ divr16u::return#2 ] zp[2]:47 [ divr16u::return#3 ] -Uplifting [print_uchar] best 13936 combination reg byte a [ print_uchar::$0 ] reg byte x [ print_uchar::$2 ] reg byte x [ print_uchar::b#3 print_uchar::b#2 print_uchar::b#0 print_uchar::b#1 ] -Uplifting [memset] best 13936 combination zp[2]:13 [ memset::dst#2 memset::dst#1 ] -Uplifting [lin16u_gen] best 13936 combination zp[2]:19 [ lin16u_gen::i#2 lin16u_gen::i#1 ] zp[2]:55 [ lin16u_gen::$6 ] zp[4]:21 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] zp[2]:25 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] zp[2]:41 [ lin16u_gen::ampl#0 ] zp[2]:49 [ lin16u_gen::stepf#0 ] zp[4]:51 [ lin16u_gen::step#0 ] zp[2]:15 [ lin16u_gen::max#3 ] zp[2]:45 [ lin16u_gen::stepi#0 ] zp[2]:17 [ lin16u_gen::min#3 ] -Uplifting [print_uint] best 13936 combination zp[2]:5 [ print_uint::w#10 print_uint::w#3 print_uint::w#4 print_uint::w#5 ] -Uplifting [main] best 13816 combination zp[1]:2 [ main::i#10 main::i#1 ] reg byte a [ main::$27 ] reg byte a [ main::$28 ] reg byte a [ main::$29 ] +Uplifting [print_char] best 14134 combination reg byte a [ print_char::ch#3 print_char::ch#0 print_char::ch#1 print_char::ch#2 ] +Uplifting [] best 14134 combination zp[2]:9 [ print_char_cursor#87 print_char_cursor#50 print_char_cursor#82 print_char_cursor#102 print_char_cursor#2 print_char_cursor#11 print_char_cursor#98 ] zp[2]:3 [ print_line_cursor#11 print_line_cursor#21 print_line_cursor#1 ] zp[2]:57 [ rem16u#1 ] +Uplifting [print_str] best 14134 combination zp[2]:11 [ print_str::str#10 print_str::str#13 print_str::str#0 ] +Uplifting [divr16u] best 13924 combination zp[2]:27 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] reg byte a [ divr16u::$1 ] reg byte a [ divr16u::$2 ] reg byte x [ divr16u::i#2 divr16u::i#1 ] zp[2]:29 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] zp[2]:41 [ divr16u::return#2 ] zp[2]:45 [ divr16u::return#3 ] +Uplifting [print_uchar] best 13876 combination reg byte a [ print_uchar::$0 ] reg byte x [ print_uchar::$2 ] reg byte x [ print_uchar::b#3 print_uchar::b#2 print_uchar::b#0 print_uchar::b#1 ] +Uplifting [memset] best 13876 combination zp[2]:13 [ memset::dst#2 memset::dst#1 ] +Uplifting [lin16u_gen] best 13876 combination zp[2]:19 [ lin16u_gen::i#2 lin16u_gen::i#1 ] zp[2]:53 [ lin16u_gen::$6 ] zp[4]:21 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] zp[2]:25 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] zp[2]:39 [ lin16u_gen::ampl#0 ] zp[2]:47 [ lin16u_gen::stepf#0 ] zp[4]:49 [ lin16u_gen::step#0 ] zp[2]:15 [ lin16u_gen::max#3 ] zp[2]:43 [ lin16u_gen::stepi#0 ] zp[2]:17 [ lin16u_gen::min#3 ] +Uplifting [print_uint] best 13876 combination zp[2]:5 [ print_uint::w#10 print_uint::w#3 print_uint::w#4 print_uint::w#5 ] +Uplifting [main] best 13756 combination zp[1]:2 [ main::i#10 main::i#1 ] reg byte a [ main::$27 ] reg byte a [ main::$28 ] reg byte a [ main::$29 ] Limited combination testing to 100 combinations of 128 possible. -Uplifting [RADIX] best 13816 combination -Uplifting [print_ln] best 13816 combination -Uplifting [print_cls] best 13816 combination +Uplifting [RADIX] best 13756 combination +Uplifting [print_ln] best 13756 combination +Uplifting [print_cls] best 13756 combination Attempting to uplift remaining variables inzp[1]:2 [ main::i#10 main::i#1 ] -Uplifting [main] best 13816 combination zp[1]:2 [ main::i#10 main::i#1 ] -Coalescing zero page register [ zp[2]:29 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] ] with [ zp[2]:59 [ rem16u#1 ] ] - score: 2 -Coalescing zero page register [ zp[2]:15 [ lin16u_gen::max#3 ] ] with [ zp[2]:41 [ lin16u_gen::ampl#0 ] ] - score: 1 -Coalescing zero page register [ zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] ] with [ zp[2]:43 [ divr16u::return#2 ] ] - score: 1 -Coalescing zero page register [ zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 ] ] with [ zp[2]:47 [ divr16u::return#3 ] ] - score: 1 -Coalescing zero page register [ zp[2]:15 [ lin16u_gen::max#3 lin16u_gen::ampl#0 ] ] with [ zp[2]:31 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] ] - score: 1 -Coalescing zero page register [ zp[2]:33 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 divr16u::return#3 ] ] with [ zp[2]:49 [ lin16u_gen::stepf#0 ] ] - score: 1 +Uplifting [main] best 13756 combination zp[1]:2 [ main::i#10 main::i#1 ] +Coalescing zero page register [ zp[2]:27 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 ] ] with [ zp[2]:57 [ rem16u#1 ] ] - score: 2 +Coalescing zero page register [ zp[2]:15 [ lin16u_gen::max#3 ] ] with [ zp[2]:39 [ lin16u_gen::ampl#0 ] ] - score: 1 +Coalescing zero page register [ zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 ] ] with [ zp[2]:41 [ divr16u::return#2 ] ] - score: 1 +Coalescing zero page register [ zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 ] ] with [ zp[2]:45 [ divr16u::return#3 ] ] - score: 1 +Coalescing zero page register [ zp[2]:15 [ lin16u_gen::max#3 lin16u_gen::ampl#0 ] ] with [ zp[2]:29 [ divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] ] - score: 1 +Coalescing zero page register [ zp[2]:31 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 divr16u::return#3 ] ] with [ zp[2]:47 [ lin16u_gen::stepf#0 ] ] - score: 1 Coalescing zero page register [ zp[2]:11 [ print_str::str#10 print_str::str#13 print_str::str#0 ] ] with [ zp[2]:5 [ print_uint::w#10 print_uint::w#3 print_uint::w#4 print_uint::w#5 ] ] Coalescing zero page register [ zp[2]:15 [ lin16u_gen::max#3 lin16u_gen::ampl#0 divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 ] ] with [ zp[2]:13 [ memset::dst#2 memset::dst#1 ] ] -Coalescing zero page register [ zp[2]:55 [ lin16u_gen::$6 ] ] with [ zp[2]:27 [ divr16u::divisor#6 ] ] Coalescing zero page register [ zp[2]:15 [ lin16u_gen::max#3 lin16u_gen::ampl#0 divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 memset::dst#2 memset::dst#1 ] ] with [ zp[2]:11 [ print_str::str#10 print_str::str#13 print_str::str#0 print_uint::w#10 print_uint::w#3 print_uint::w#4 print_uint::w#5 ] ] Allocated (was zp[2]:9) zp[2]:5 [ print_char_cursor#87 print_char_cursor#50 print_char_cursor#82 print_char_cursor#102 print_char_cursor#2 print_char_cursor#11 print_char_cursor#98 ] Allocated (was zp[2]:15) zp[2]:7 [ lin16u_gen::max#3 lin16u_gen::ampl#0 divr16u::dividend#3 divr16u::dividend#5 divr16u::dividend#1 divr16u::dividend#0 memset::dst#2 memset::dst#1 print_str::str#10 print_str::str#13 print_str::str#0 print_uint::w#10 print_uint::w#3 print_uint::w#4 print_uint::w#5 ] @@ -3519,11 +3503,11 @@ Allocated (was zp[2]:17) zp[2]:9 [ lin16u_gen::min#3 ] Allocated (was zp[2]:19) zp[2]:11 [ lin16u_gen::i#2 lin16u_gen::i#1 ] Allocated (was zp[4]:21) zp[4]:13 [ lin16u_gen::val#2 lin16u_gen::val#1 lin16u_gen::val#0 ] Allocated (was zp[2]:25) zp[2]:17 [ lin16u_gen::lintab#4 lin16u_gen::lintab#3 lin16u_gen::lintab#6 ] -Allocated (was zp[2]:29) zp[2]:19 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 rem16u#1 ] -Allocated (was zp[2]:33) zp[2]:21 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 divr16u::return#3 lin16u_gen::stepf#0 ] -Allocated (was zp[2]:45) zp[2]:23 [ lin16u_gen::stepi#0 ] -Allocated (was zp[4]:51) zp[4]:25 [ lin16u_gen::step#0 ] -Allocated (was zp[2]:55) zp[2]:29 [ lin16u_gen::$6 divr16u::divisor#6 ] +Allocated (was zp[2]:27) zp[2]:19 [ divr16u::rem#5 divr16u::rem#10 divr16u::rem#4 divr16u::rem#11 divr16u::rem#6 divr16u::rem#0 divr16u::rem#1 divr16u::rem#2 rem16u#1 ] +Allocated (was zp[2]:31) zp[2]:21 [ divr16u::quotient#3 divr16u::return#0 divr16u::quotient#1 divr16u::quotient#2 divr16u::return#2 divr16u::return#3 lin16u_gen::stepf#0 ] +Allocated (was zp[2]:43) zp[2]:23 [ lin16u_gen::stepi#0 ] +Allocated (was zp[4]:49) zp[4]:25 [ lin16u_gen::step#0 ] +Allocated (was zp[2]:53) zp[2]:29 [ lin16u_gen::$6 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -4246,13 +4230,8 @@ lin16u_gen: { // [106] call divr16u // [123] phi from lin16u_gen to divr16u [phi:lin16u_gen->divr16u] divr16u_from_lin16u_gen: - // [123] phi (word) divr16u::divisor#6 = (byte) $14-(byte) 1 [phi:lin16u_gen->divr16u#0] -- vwuz1=vbuc1 - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 - // [123] phi (word) divr16u::dividend#5 = (word) divr16u::dividend#1 [phi:lin16u_gen->divr16u#1] -- register_copy - // [123] phi (word) divr16u::rem#10 = (byte) 0 [phi:lin16u_gen->divr16u#2] -- vwuz1=vbuc1 + // [123] phi (word) divr16u::dividend#5 = (word) divr16u::dividend#1 [phi:lin16u_gen->divr16u#0] -- register_copy + // [123] phi (word) divr16u::rem#10 = (byte) 0 [phi:lin16u_gen->divr16u#1] -- vwuz1=vbuc1 lda #<0 sta.z divr16u.rem lda #>0 @@ -4271,17 +4250,12 @@ lin16u_gen: { // [110] call divr16u // [123] phi from lin16u_gen::@3 to divr16u [phi:lin16u_gen::@3->divr16u] divr16u_from___b3: - // [123] phi (word) divr16u::divisor#6 = (byte) $14-(byte) 1 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 - // [123] phi (word) divr16u::dividend#5 = (byte) 0 [phi:lin16u_gen::@3->divr16u#1] -- vwuz1=vbuc1 + // [123] phi (word) divr16u::dividend#5 = (byte) 0 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 lda #<0 sta.z divr16u.dividend lda #>0 sta.z divr16u.dividend+1 - // [123] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#2] -- register_copy + // [123] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#1] -- register_copy jsr divr16u // [111] (word) divr16u::return#3 ← (word) divr16u::return#0 jmp __b4 @@ -4385,13 +4359,12 @@ lin16u_gen: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zp(7) dividend, word zp($1d) divisor, word zp($13) rem) +// divr16u(word zp(7) dividend, word zp($13) rem) divr16u: { .label rem = $13 .label dividend = 7 .label quotient = $15 .label return = $15 - .label divisor = $1d // [124] phi from divr16u to divr16u::@1 [phi:divr16u->divr16u::@1] __b1_from_divr16u: // [124] phi (byte) divr16u::i#2 = (byte) 0 [phi:divr16u->divr16u::@1#0] -- vbuxx=vbuc1 @@ -4443,13 +4416,13 @@ divr16u: { // [132] (word) divr16u::quotient#1 ← (word) divr16u::quotient#3 << (byte) 1 -- vwuz1=vwuz1_rol_1 asl.z quotient rol.z quotient+1 - // [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 -- vwuz1_lt_vwuz2_then_la1 + // [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 -- vwuz1_lt_vbuc1_then_la1 lda.z rem+1 - cmp.z divisor+1 + cmp #>$14-1 bcc __b3_from___b2 bne !+ lda.z rem - cmp.z divisor + cmp #<$14-1 bcc __b3_from___b2 !: jmp __b5 @@ -4460,13 +4433,13 @@ divr16u: { bne !+ inc.z quotient+1 !: - // [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 -- vwuz1=vwuz1_minus_vwuz2 + // [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 -- vwuz1=vwuz1_minus_vwuc1 lda.z rem sec - sbc.z divisor + sbc #<$14-1 sta.z rem lda.z rem+1 - sbc.z divisor+1 + sbc #>$14-1 sta.z rem+1 // [136] phi from divr16u::@2 divr16u::@5 to divr16u::@3 [phi:divr16u::@2/divr16u::@5->divr16u::@3] __b3_from___b2: @@ -4718,7 +4691,6 @@ FINAL SYMBOL TABLE (word) divr16u::dividend#3 dividend zp[2]:7 4429.142857142857 (word) divr16u::dividend#5 dividend zp[2]:7 1102.0 (word) divr16u::divisor -(word) divr16u::divisor#6 divisor zp[2]:29 1250.125 (byte) divr16u::i (byte) divr16u::i#1 reg byte x 15001.5 (byte) divr16u::i#2 reg byte x 1538.6153846153845 @@ -4902,13 +4874,13 @@ reg byte a [ print_uchar::$0 ] reg byte x [ print_uchar::$2 ] zp[2]:23 [ lin16u_gen::stepi#0 ] zp[4]:25 [ lin16u_gen::step#0 ] -zp[2]:29 [ lin16u_gen::$6 divr16u::divisor#6 ] +zp[2]:29 [ lin16u_gen::$6 ] reg byte a [ divr16u::$1 ] reg byte a [ divr16u::$2 ] FINAL ASSEMBLER -Score: 11879 +Score: 11819 // File Comments // Linear table generator @@ -5538,13 +5510,8 @@ lin16u_gen: { // [105] (word) divr16u::dividend#1 ← (word) lin16u_gen::ampl#0 // [106] call divr16u // [123] phi from lin16u_gen to divr16u [phi:lin16u_gen->divr16u] - // [123] phi (word) divr16u::divisor#6 = (byte) $14-(byte) 1 [phi:lin16u_gen->divr16u#0] -- vwuz1=vbuc1 - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 - // [123] phi (word) divr16u::dividend#5 = (word) divr16u::dividend#1 [phi:lin16u_gen->divr16u#1] -- register_copy - // [123] phi (word) divr16u::rem#10 = (byte) 0 [phi:lin16u_gen->divr16u#2] -- vwuz1=vbuc1 + // [123] phi (word) divr16u::dividend#5 = (word) divr16u::dividend#1 [phi:lin16u_gen->divr16u#0] -- register_copy + // [123] phi (word) divr16u::rem#10 = (byte) 0 [phi:lin16u_gen->divr16u#1] -- vwuz1=vbuc1 lda #<0 sta.z divr16u.rem sta.z divr16u.rem+1 @@ -5562,16 +5529,11 @@ lin16u_gen: { // [109] (word) divr16u::rem#4 ← (word) rem16u#1 // [110] call divr16u // [123] phi from lin16u_gen::@3 to divr16u [phi:lin16u_gen::@3->divr16u] - // [123] phi (word) divr16u::divisor#6 = (byte) $14-(byte) 1 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 - lda #<$14-1 - sta.z divr16u.divisor - lda #>$14-1 - sta.z divr16u.divisor+1 - // [123] phi (word) divr16u::dividend#5 = (byte) 0 [phi:lin16u_gen::@3->divr16u#1] -- vwuz1=vbuc1 + // [123] phi (word) divr16u::dividend#5 = (byte) 0 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 lda #<0 sta.z divr16u.dividend sta.z divr16u.dividend+1 - // [123] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#2] -- register_copy + // [123] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#1] -- register_copy jsr divr16u // divr16u(0, length-1, rem16u) // [111] (word) divr16u::return#3 ← (word) divr16u::return#0 @@ -5677,13 +5639,12 @@ lin16u_gen: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zp(7) dividend, word zp($1d) divisor, word zp($13) rem) +// divr16u(word zp(7) dividend, word zp($13) rem) divr16u: { .label rem = $13 .label dividend = 7 .label quotient = $15 .label return = $15 - .label divisor = $1d // [124] phi from divr16u to divr16u::@1 [phi:divr16u->divr16u::@1] // [124] phi (byte) divr16u::i#2 = (byte) 0 [phi:divr16u->divr16u::@1#0] -- vbuxx=vbuc1 ldx #0 @@ -5733,13 +5694,13 @@ divr16u: { asl.z quotient rol.z quotient+1 // if(rem>=divisor) - // [133] if((word) divr16u::rem#6<(word) divr16u::divisor#6) goto divr16u::@3 -- vwuz1_lt_vwuz2_then_la1 + // [133] if((word) divr16u::rem#6<(byte) $14-(byte) 1) goto divr16u::@3 -- vwuz1_lt_vbuc1_then_la1 lda.z rem+1 - cmp.z divisor+1 + cmp #>$14-1 bcc __b3 bne !+ lda.z rem - cmp.z divisor + cmp #<$14-1 bcc __b3 !: // divr16u::@5 @@ -5750,13 +5711,13 @@ divr16u: { inc.z quotient+1 !: // rem = rem - divisor - // [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (word) divr16u::divisor#6 -- vwuz1=vwuz1_minus_vwuz2 + // [135] (word) divr16u::rem#2 ← (word) divr16u::rem#6 - (byte) $14-(byte) 1 -- vwuz1=vwuz1_minus_vwuc1 lda.z rem sec - sbc.z divisor + sbc #<$14-1 sta.z rem lda.z rem+1 - sbc.z divisor+1 + sbc #>$14-1 sta.z rem+1 // [136] phi from divr16u::@2 divr16u::@5 to divr16u::@3 [phi:divr16u::@2/divr16u::@5->divr16u::@3] // [136] phi (word) divr16u::return#0 = (word) divr16u::quotient#1 [phi:divr16u::@2/divr16u::@5->divr16u::@3#0] -- register_copy diff --git a/src/test/ref/linegen.sym b/src/test/ref/linegen.sym index c15b02045..5edfcfd4e 100644 --- a/src/test/ref/linegen.sym +++ b/src/test/ref/linegen.sym @@ -22,7 +22,6 @@ (word) divr16u::dividend#3 dividend zp[2]:7 4429.142857142857 (word) divr16u::dividend#5 dividend zp[2]:7 1102.0 (word) divr16u::divisor -(word) divr16u::divisor#6 divisor zp[2]:29 1250.125 (byte) divr16u::i (byte) divr16u::i#1 reg byte x 15001.5 (byte) divr16u::i#2 reg byte x 1538.6153846153845 @@ -206,6 +205,6 @@ reg byte a [ print_uchar::$0 ] reg byte x [ print_uchar::$2 ] zp[2]:23 [ lin16u_gen::stepi#0 ] zp[4]:25 [ lin16u_gen::step#0 ] -zp[2]:29 [ lin16u_gen::$6 divr16u::divisor#6 ] +zp[2]:29 [ lin16u_gen::$6 ] reg byte a [ divr16u::$1 ] reg byte a [ divr16u::$2 ]