From 97f88fb128817a914d67df9d9aab3d970bc12ec1 Mon Sep 17 00:00:00 2001 From: Jesper Gravgaard <jg@ramboll.com> Date: Wed, 10 Apr 2019 16:06:03 +0200 Subject: [PATCH] Fixed comparison optimization to ignore 0 --- .../passes/Pass2ComparisonOptimization.java | 15 ++- .../dk/camelot64/kickc/test/TestPrograms.java | 2 +- src/test/ref/complex-conditional-problem.asm | 4 +- src/test/ref/complex-conditional-problem.cfg | 2 +- src/test/ref/complex-conditional-problem.log | 29 +++--- src/test/ref/complex/tetris/tetris.asm | 14 +-- src/test/ref/complex/tetris/tetris.cfg | 4 +- src/test/ref/complex/tetris/tetris.log | 66 ++++++------- src/test/ref/const-identification.asm | 3 +- src/test/ref/const-identification.cfg | 2 +- src/test/ref/const-identification.log | 26 +++--- src/test/ref/examples/fire/fire.asm | 6 +- src/test/ref/examples/fire/fire.cfg | 4 +- src/test/ref/examples/fire/fire.log | 74 +++++++-------- src/test/ref/irq-volatile-bool-problem.asm | 3 +- src/test/ref/irq-volatile-bool-problem.cfg | 2 +- src/test/ref/irq-volatile-bool-problem.log | 28 +++--- src/test/ref/longbranch-interrupt-problem.asm | 6 +- src/test/ref/longbranch-interrupt-problem.cfg | 2 +- src/test/ref/longbranch-interrupt-problem.log | 29 +++--- src/test/ref/loopmin.asm | 3 +- src/test/ref/loopmin.cfg | 2 +- src/test/ref/loopmin.log | 28 +++--- src/test/ref/loopsplit.asm | 17 ++-- src/test/ref/loopsplit.cfg | 2 +- src/test/ref/loopsplit.log | 93 +++++++++---------- src/test/ref/loopsplit.sym | 14 +-- src/test/ref/roll-sprite-msb.asm | 5 +- src/test/ref/roll-sprite-msb.cfg | 2 +- src/test/ref/roll-sprite-msb.log | 42 +++++---- src/test/ref/test-comparisons.asm | 12 +-- src/test/ref/test-comparisons.cfg | 4 +- src/test/ref/test-comparisons.log | 58 ++++++------ .../ref/test-interrupt-volatile-write.asm | 6 +- .../ref/test-interrupt-volatile-write.cfg | 2 +- .../ref/test-interrupt-volatile-write.log | 29 +++--- 36 files changed, 313 insertions(+), 327 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java index 13549b860..984901929 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java @@ -1,5 +1,6 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.operators.Operator; @@ -41,10 +42,17 @@ public class Pass2ComparisonOptimization extends Pass2SsaOptimization { if(conditionalJump.getrValue2() instanceof ConstantValue) { SymbolType valueType = SymbolTypeInference.inferType(getScope(), conditionalJump.getrValue1()); ConstantValue constantValue = (ConstantValue) conditionalJump.getrValue2(); - ConstantLiteral constantLiteral = constantValue.calculateLiteral(getScope()); + ConstantLiteral constantLiteral = null; + try { + constantLiteral = constantValue.calculateLiteral(getScope()); + } catch(ConstantNotLiteral e) { + System.out.println(e); + // Ignore + } if(Operators.GT.equals(operator) && valueType instanceof SymbolTypeInteger && constantLiteral instanceof ConstantInteger) { // Found > C - rewrite to >= C+1 if possible - if(((Long) constantLiteral.getValue()) < ((SymbolTypeInteger) valueType).getMaxValue()) { + Long longValue = (Long) constantLiteral.getValue(); + if(longValue < ((SymbolTypeInteger) valueType).getMaxValue() && longValue != 0L) { // Rewrite is possible - do it getLog().append("Rewriting conditional comparison " + statement.toString(getProgram(), false)); conditionalJump.setOperator(Operators.GE); @@ -53,7 +61,8 @@ public class Pass2ComparisonOptimization extends Pass2SsaOptimization { } if(Operators.LE.equals(operator) && valueType instanceof SymbolTypeInteger && constantLiteral instanceof ConstantInteger) { // Found <= C - rewrite to < C+1 if possible - if(((Long) constantLiteral.getValue()) < ((SymbolTypeInteger) valueType).getMaxValue()) { + Long longValue = (Long) constantLiteral.getValue(); + if(longValue < ((SymbolTypeInteger) valueType).getMaxValue() && longValue != 0L) { // Rewrite is possible - do it getLog().append("Rewriting conditional comparison " + statement.toString(getProgram(), false)); conditionalJump.setOperator(Operators.LT); diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 3176dab22..054886017 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -189,7 +189,7 @@ public class TestPrograms { @Test public void testComparisonRewriting() throws IOException, URISyntaxException { - compileAndCompare("comparison-rewriting", getLogSysout()); + compileAndCompare("comparison-rewriting"); } @Test diff --git a/src/test/ref/complex-conditional-problem.asm b/src/test/ref/complex-conditional-problem.asm index 7245ec521..ec0d49551 100644 --- a/src/test/ref/complex-conditional-problem.asm +++ b/src/test/ref/complex-conditional-problem.asm @@ -7,10 +7,8 @@ main: { b1: lda RASTER - cmp #$20 - beq !+ + cmp #$20+1 bcs b3 - !: cmp #$40 bcc b3 b2: diff --git a/src/test/ref/complex-conditional-problem.cfg b/src/test/ref/complex-conditional-problem.cfg index 2e35816cb..82ab34590 100644 --- a/src/test/ref/complex-conditional-problem.cfg +++ b/src/test/ref/complex-conditional-problem.cfg @@ -12,7 +12,7 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@2 [5] (byte) main::key#0 ← *((const byte*) RASTER#0) - [6] if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@3 + [6] if((byte) main::key#0>=(byte/signed byte/word/signed word/dword/signed dword) $20+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 to:main::@4 main::@4: scope:[main] from main::@1 [7] if((byte) main::key#0<(byte/signed byte/word/signed word/dword/signed dword) $40) goto main::@3 diff --git a/src/test/ref/complex-conditional-problem.log b/src/test/ref/complex-conditional-problem.log index a558bce82..79b4339ce 100644 --- a/src/test/ref/complex-conditional-problem.log +++ b/src/test/ref/complex-conditional-problem.log @@ -77,6 +77,7 @@ Successful SSA optimization Pass2CullEmptyBlocks Simple Condition (bool~) main::$0 [3] if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@7 Simple Condition (bool~) main::$1 [7] if((byte) main::key#0<(byte/signed byte/word/signed word/dword/signed dword) $40) goto main::@7 Successful SSA optimization Pass2ConditionalJumpSimplification +Rewriting conditional comparison if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@7 Inlining constant with var siblings (const byte) main::key#1 Constant inlined main::key#1 = (byte/signed byte/word/signed word/dword/signed dword) 0 Successful SSA optimization Pass2ConstantInlining @@ -118,7 +119,7 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@2 [5] (byte) main::key#0 ← *((const byte*) RASTER#0) - [6] if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@3 + [6] if((byte) main::key#0>=(byte/signed byte/word/signed word/dword/signed dword) $20+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 to:main::@4 main::@4: scope:[main] from main::@1 [7] if((byte) main::key#0<(byte/signed byte/word/signed word/dword/signed dword) $40) goto main::@3 @@ -181,10 +182,10 @@ main: { //SEG12 [5] (byte) main::key#0 ← *((const byte*) RASTER#0) -- vbuz1=_deref_pbuc1 lda RASTER sta key - //SEG13 [6] if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@3 -- vbuz1_gt_vbuc1_then_la1 - lda #$20 - cmp key - bcc b3_from_b1 + //SEG13 [6] if((byte) main::key#0>=(byte/signed byte/word/signed word/dword/signed dword) $20+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 -- vbuz1_ge_vbuc1_then_la1 + lda key + cmp #$20+1 + bcs b3_from_b1 jmp b4 //SEG14 main::@4 b4: @@ -223,8 +224,8 @@ REGISTER UPLIFT SCOPES Uplift Scope [main] 36.67: zp ZP_BYTE:2 [ main::key#2 main::key#0 ] Uplift Scope [] -Uplifting [main] best 407 combination reg byte a [ main::key#2 main::key#0 ] -Uplifting [] best 407 combination +Uplifting [main] best 382 combination reg byte a [ main::key#2 main::key#0 ] +Uplifting [] best 382 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -259,11 +260,9 @@ main: { b1: //SEG12 [5] (byte) main::key#0 ← *((const byte*) RASTER#0) -- vbuaa=_deref_pbuc1 lda RASTER - //SEG13 [6] if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@3 -- vbuaa_gt_vbuc1_then_la1 - cmp #$20 - beq !+ + //SEG13 [6] if((byte) main::key#0>=(byte/signed byte/word/signed word/dword/signed dword) $20+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 -- vbuaa_ge_vbuc1_then_la1 + cmp #$20+1 bcs b3_from_b1 - !: jmp b4 //SEG14 main::@4 b4: @@ -341,7 +340,7 @@ reg byte a [ main::key#2 main::key#0 ] FINAL ASSEMBLER -Score: 275 +Score: 250 //SEG0 File Comments // Test to provoke Exception when using complex || condition @@ -365,11 +364,9 @@ main: { b1: //SEG12 [5] (byte) main::key#0 ← *((const byte*) RASTER#0) -- vbuaa=_deref_pbuc1 lda RASTER - //SEG13 [6] if((byte) main::key#0>(byte/signed byte/word/signed word/dword/signed dword) $20) goto main::@3 -- vbuaa_gt_vbuc1_then_la1 - cmp #$20 - beq !+ + //SEG13 [6] if((byte) main::key#0>=(byte/signed byte/word/signed word/dword/signed dword) $20+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 -- vbuaa_ge_vbuc1_then_la1 + cmp #$20+1 bcs b3 - !: //SEG14 main::@4 //SEG15 [7] if((byte) main::key#0<(byte/signed byte/word/signed word/dword/signed dword) $40) goto main::@3 -- vbuaa_lt_vbuc1_then_la1 cmp #$40 diff --git a/src/test/ref/complex/tetris/tetris.asm b/src/test/ref/complex/tetris/tetris.asm index 28f24bc4e..f6a714dba 100644 --- a/src/test/ref/complex/tetris/tetris.asm +++ b/src/test/ref/complex/tetris/tetris.asm @@ -485,9 +485,9 @@ render_moving: { sta l sta i b1: - lda #2 - cmp ypos2 - bcc b2 + lda ypos2 + cmp #2+1 + bcs b2 lax i axs #-[4] stx i @@ -959,10 +959,10 @@ play_update_score: { play_increase_level: { inc level // Update speed of moving tetrominos down - lda #$1d - cmp level - bcc b3 - ldy level + lda level + cmp #$1d+1 + bcs b3 + tay lda MOVEDOWN_SLOW_SPEEDS,y sta current_movedown_slow jmp b1 diff --git a/src/test/ref/complex/tetris/tetris.cfg b/src/test/ref/complex/tetris/tetris.cfg index 0fff16e56..43f01f241 100644 --- a/src/test/ref/complex/tetris/tetris.cfg +++ b/src/test/ref/complex/tetris/tetris.cfg @@ -303,7 +303,7 @@ render_moving::@1: scope:[render_moving] from render_moving render_moving::@3 [131] (byte) render_moving::l#4 ← phi( render_moving/(byte/signed byte/word/signed word/dword/signed dword) 0 render_moving::@3/(byte) render_moving::l#1 ) [131] (byte) render_moving::i#3 ← phi( render_moving/(byte/signed byte/word/signed word/dword/signed dword) 0 render_moving::@3/(byte) render_moving::i#8 ) [131] (byte) render_moving::ypos2#2 ← phi( render_moving/(byte) render_moving::ypos2#0 render_moving::@3/(byte) render_moving::ypos2#1 ) - [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 + [132] if((byte) render_moving::ypos2#2>=(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto render_moving::@2 to:render_moving::@7 render_moving::@7: scope:[render_moving] from render_moving::@1 [133] (byte) render_moving::i#1 ← (byte) render_moving::i#3 + (byte/signed byte/word/signed word/dword/signed dword) 4 @@ -698,7 +698,7 @@ play_update_score::@return: scope:[play_update_score] from play_update_score pl to:@return play_increase_level: scope:[play_increase_level] from play_update_score::@2 [321] (byte) level#21 ← ++ (byte) level#10 - [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 + [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 to:play_increase_level::@3 play_increase_level::@3: scope:[play_increase_level] from play_increase_level [323] (byte) current_movedown_slow#10 ← *((const byte[]) MOVEDOWN_SLOW_SPEEDS#0 + (byte) level#21) diff --git a/src/test/ref/complex/tetris/tetris.log b/src/test/ref/complex/tetris/tetris.log index e5b5421b7..2174e3ffc 100644 --- a/src/test/ref/complex/tetris/tetris.log +++ b/src/test/ref/complex/tetris/tetris.log @@ -9186,6 +9186,8 @@ Resolved ranged next value play_remove_lines::y#1 ← ++ play_remove_lines::y#8 Resolved ranged comparison value if(play_remove_lines::y#1!=rangelast(0,play_remove_lines::$4)) goto play_remove_lines::@1 to (const byte/signed word/word/dword/signed dword) play_remove_lines::$4+(byte/signed byte/word/signed word/dword/signed dword) 1 Resolved ranged next value play_increase_level::b#1 ← ++ play_increase_level::b#2 to ++ Resolved ranged comparison value if(play_increase_level::b#1!=rangelast(0,4)) goto play_increase_level::@7 to (byte/signed byte/word/signed word/dword/signed dword) 5 +Rewriting conditional comparison if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 +Rewriting conditional comparison if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 Culled Empty Block (label) @5 Culled Empty Block (label) @9 Culled Empty Block (label) keyboard_event_scan::@9 @@ -10512,7 +10514,7 @@ render_moving::@1: scope:[render_moving] from render_moving render_moving::@3 [131] (byte) render_moving::l#4 ← phi( render_moving/(byte/signed byte/word/signed word/dword/signed dword) 0 render_moving::@3/(byte) render_moving::l#1 ) [131] (byte) render_moving::i#3 ← phi( render_moving/(byte/signed byte/word/signed word/dword/signed dword) 0 render_moving::@3/(byte) render_moving::i#8 ) [131] (byte) render_moving::ypos2#2 ← phi( render_moving/(byte) render_moving::ypos2#0 render_moving::@3/(byte) render_moving::ypos2#1 ) - [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 + [132] if((byte) render_moving::ypos2#2>=(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto render_moving::@2 to:render_moving::@7 render_moving::@7: scope:[render_moving] from render_moving::@1 [133] (byte) render_moving::i#1 ← (byte) render_moving::i#3 + (byte/signed byte/word/signed word/dword/signed dword) 4 @@ -10907,7 +10909,7 @@ play_update_score::@return: scope:[play_update_score] from play_update_score pl to:@return play_increase_level: scope:[play_increase_level] from play_update_score::@2 [321] (byte) level#21 ← ++ (byte) level#10 - [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 + [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 to:play_increase_level::@3 play_increase_level::@3: scope:[play_increase_level] from play_increase_level [323] (byte) current_movedown_slow#10 ← *((const byte[]) MOVEDOWN_SLOW_SPEEDS#0 + (byte) level#21) @@ -13931,10 +13933,10 @@ render_moving: { jmp b1 //SEG330 render_moving::@1 b1: - //SEG331 [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 -- vbuz1_gt_vbuc1_then_la1 - lda #2 - cmp ypos2 - bcc b2 + //SEG331 [132] if((byte) render_moving::ypos2#2>=(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto render_moving::@2 -- vbuz1_ge_vbuc1_then_la1 + lda ypos2 + cmp #2+1 + bcs b2 jmp b7 //SEG332 render_moving::@7 b7: @@ -15142,11 +15144,11 @@ play_increase_level: { .label b = $4c //SEG760 [321] (byte) level#21 ← ++ (byte) level#10 -- vbuz1=_inc_vbuz1 inc level - //SEG761 [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 -- vbuz1_gt_vbuc1_then_la1 + //SEG761 [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 -- vbuz1_ge_vbuc1_then_la1 // Update speed of moving tetrominos down - lda #$1d - cmp level - bcc b1_from_play_increase_level + lda level + cmp #$1d+1 + bcs b1_from_play_increase_level jmp b3 //SEG762 play_increase_level::@3 b3: @@ -16996,7 +16998,6 @@ Statement [309] (dword) play_update_score::add_bcd#0 ← *((const dword[5]) scor Statement [311] (word) lines_bcd#30 ← (word) lines_bcd#19 + (byte) play_update_score::removed#0 [ current_movedown_slow#14 score_bcd#18 level#10 level_bcd#11 play_update_score::lines_before#0 play_update_score::add_bcd#0 lines_bcd#30 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 score_bcd#18 level#10 level_bcd#11 play_update_score::lines_before#0 play_update_score::add_bcd#0 lines_bcd#30 ] ) always clobbers reg byte a Statement [312] (dword) score_bcd#30 ← (dword) score_bcd#18 + (dword) play_update_score::add_bcd#0 [ current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 ] ) always clobbers reg byte a Statement [314] (byte~) play_update_score::$5 ← < (word) lines_bcd#30 [ current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 play_update_score::$5 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 play_update_score::$5 ] ) always clobbers reg byte a -Statement [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 [ level_bcd#11 level#21 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 ] ) always clobbers reg byte a Statement [326] (byte~) play_increase_level::$1 ← (byte) level_bcd#21 & (byte/signed byte/word/signed word/dword/signed dword) $f [ level#21 current_movedown_slow#69 level_bcd#21 play_increase_level::$1 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level#21 current_movedown_slow#69 level_bcd#21 play_increase_level::$1 ] ) always clobbers reg byte a Statement [328] (byte) level_bcd#8 ← (byte) level_bcd#21 + (byte/signed byte/word/signed word/dword/signed dword) 6 [ level#21 current_movedown_slow#69 level_bcd#8 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level#21 current_movedown_slow#69 level_bcd#8 ] ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte x as potential for zp ZP_BYTE:2 [ render_screen_show#16 render_screen_show#13 ] @@ -17171,7 +17172,6 @@ Statement [120] *((byte*) render_next::screen_next_area#5) ← (byte/signed byte Statement [124] (byte*) render_next::screen_next_area#4 ← (byte*) render_next::screen_next_area#3 + (byte/signed byte/word/signed word/dword/signed dword) $24 [ render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#4 ] ( main:12::render_next:36 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#4 ] main:12::render_next:65 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#4 ] ) always clobbers reg byte a Statement [128] *((byte*) render_next::screen_next_area#5) ← (byte) render_next::next_piece_char#0 [ render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#5 render_next::c#2 ] ( main:12::render_next:36 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#5 render_next::c#2 ] main:12::render_next:65 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#5 render_next::c#2 ] ) always clobbers reg byte a reg byte y Statement [130] (byte) render_moving::ypos2#0 ← (byte) current_ypos#13 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#0 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#0 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#0 ] ) always clobbers reg byte a -Statement [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 ] ) always clobbers reg byte a Statement [133] (byte) render_moving::i#1 ← (byte) render_moving::i#3 + (byte/signed byte/word/signed word/dword/signed dword) 4 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::l#4 render_moving::i#1 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::l#4 render_moving::i#1 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::l#4 render_moving::i#1 ] ) always clobbers reg byte a Statement [139] (byte~) render_moving::$2 ← (byte) render_screen_render#33 + (byte) render_moving::ypos2#2 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::$2 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::$2 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::$2 ] ) always clobbers reg byte a Statement [140] (byte*) render_moving::screen_line#0 ← *((const byte*[PLAYFIELD_LINES#0]) screen_lines_1#0 + (byte~) render_moving::$2) [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::screen_line#0 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::screen_line#0 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::screen_line#0 ] ) always clobbers reg byte a @@ -17209,7 +17209,7 @@ Statement [309] (dword) play_update_score::add_bcd#0 ← *((const dword[5]) scor Statement [311] (word) lines_bcd#30 ← (word) lines_bcd#19 + (byte) play_update_score::removed#0 [ current_movedown_slow#14 score_bcd#18 level#10 level_bcd#11 play_update_score::lines_before#0 play_update_score::add_bcd#0 lines_bcd#30 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 score_bcd#18 level#10 level_bcd#11 play_update_score::lines_before#0 play_update_score::add_bcd#0 lines_bcd#30 ] ) always clobbers reg byte a Statement [312] (dword) score_bcd#30 ← (dword) score_bcd#18 + (dword) play_update_score::add_bcd#0 [ current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 ] ) always clobbers reg byte a Statement [314] (byte~) play_update_score::$5 ← < (word) lines_bcd#30 [ current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 play_update_score::$5 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 play_update_score::$5 ] ) always clobbers reg byte a -Statement [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 [ level_bcd#11 level#21 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 ] ) always clobbers reg byte a +Statement [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 [ level_bcd#11 level#21 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 ] ) always clobbers reg byte a Statement [323] (byte) current_movedown_slow#10 ← *((const byte[]) MOVEDOWN_SLOW_SPEEDS#0 + (byte) level#21) [ level_bcd#11 level#21 current_movedown_slow#10 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 current_movedown_slow#10 ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte y as potential for zp ZP_BYTE:126 [ play_movement::key_event#0 ] Statement [326] (byte~) play_increase_level::$1 ← (byte) level_bcd#21 & (byte/signed byte/word/signed word/dword/signed dword) $f [ level#21 current_movedown_slow#69 level_bcd#21 play_increase_level::$1 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level#21 current_movedown_slow#69 level_bcd#21 play_increase_level::$1 ] ) always clobbers reg byte a @@ -17353,7 +17353,6 @@ Statement [120] *((byte*) render_next::screen_next_area#5) ← (byte/signed byte Statement [124] (byte*) render_next::screen_next_area#4 ← (byte*) render_next::screen_next_area#3 + (byte/signed byte/word/signed word/dword/signed dword) $24 [ render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#4 ] ( main:12::render_next:36 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#4 ] main:12::render_next:65 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#4 ] ) always clobbers reg byte a Statement [128] *((byte*) render_next::screen_next_area#5) ← (byte) render_next::next_piece_char#0 [ render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#5 render_next::c#2 ] ( main:12::render_next:36 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#5 render_next::c#2 ] main:12::render_next:65 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_next::next_piece_char#0 render_next::l#7 render_next::next_piece_gfx#1 render_next::screen_next_area#5 render_next::c#2 ] ) always clobbers reg byte a reg byte y Statement [130] (byte) render_moving::ypos2#0 ← (byte) current_ypos#13 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#0 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#0 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#0 ] ) always clobbers reg byte a -Statement [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 ] ) always clobbers reg byte a Statement [133] (byte) render_moving::i#1 ← (byte) render_moving::i#3 + (byte/signed byte/word/signed word/dword/signed dword) 4 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::l#4 render_moving::i#1 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::l#4 render_moving::i#1 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::l#4 render_moving::i#1 ] ) always clobbers reg byte a Statement [139] (byte~) render_moving::$2 ← (byte) render_screen_render#33 + (byte) render_moving::ypos2#2 [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::$2 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::$2 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::$2 ] ) always clobbers reg byte a Statement [140] (byte*) render_moving::screen_line#0 ← *((const byte*[PLAYFIELD_LINES#0]) screen_lines_1#0 + (byte~) render_moving::$2) [ render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::screen_line#0 ] ( main:12::render_moving:34 [ current_ypos#6 current_xpos#103 current_piece_gfx#74 current_piece_char#5 play_spawn_current::piece_idx#2 play_spawn_current::$0 current_movedown_slow#1 game_over#52 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::screen_line#0 ] main:12::render_moving:62 [ render_screen_show#16 render_screen_render#18 current_movedown_slow#21 current_piece#15 current_piece_char#16 current_orientation#17 current_piece_gfx#18 current_xpos#19 current_ypos#19 game_over#15 next_piece_idx#16 keyboard_events_size#16 current_movedown_counter#14 lines_bcd#15 score_bcd#14 level#17 level_bcd#17 render_screen_render#33 current_xpos#59 current_piece_gfx#64 current_piece_char#68 render_moving::ypos2#2 render_moving::i#3 render_moving::l#4 render_moving::screen_line#0 ] ) always clobbers reg byte a @@ -17396,7 +17395,7 @@ Statement [309] (dword) play_update_score::add_bcd#0 ← *((const dword[5]) scor Statement [311] (word) lines_bcd#30 ← (word) lines_bcd#19 + (byte) play_update_score::removed#0 [ current_movedown_slow#14 score_bcd#18 level#10 level_bcd#11 play_update_score::lines_before#0 play_update_score::add_bcd#0 lines_bcd#30 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 score_bcd#18 level#10 level_bcd#11 play_update_score::lines_before#0 play_update_score::add_bcd#0 lines_bcd#30 ] ) always clobbers reg byte a Statement [312] (dword) score_bcd#30 ← (dword) score_bcd#18 + (dword) play_update_score::add_bcd#0 [ current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 ] ) always clobbers reg byte a Statement [314] (byte~) play_update_score::$5 ← < (word) lines_bcd#30 [ current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 play_update_score::$5 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 current_movedown_slow#14 level#10 level_bcd#11 play_update_score::lines_before#0 lines_bcd#30 score_bcd#30 play_update_score::$5 ] ) always clobbers reg byte a -Statement [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 [ level_bcd#11 level#21 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 ] ) always clobbers reg byte a +Statement [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 [ level_bcd#11 level#21 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 ] ) always clobbers reg byte a Statement [323] (byte) current_movedown_slow#10 ← *((const byte[]) MOVEDOWN_SLOW_SPEEDS#0 + (byte) level#21) [ level_bcd#11 level#21 current_movedown_slow#10 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level_bcd#11 level#21 current_movedown_slow#10 ] ) always clobbers reg byte a reg byte y Statement [326] (byte~) play_increase_level::$1 ← (byte) level_bcd#21 & (byte/signed byte/word/signed word/dword/signed dword) $f [ level#21 current_movedown_slow#69 level_bcd#21 play_increase_level::$1 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level#21 current_movedown_slow#69 level_bcd#21 play_increase_level::$1 ] ) always clobbers reg byte a Statement [328] (byte) level_bcd#8 ← (byte) level_bcd#21 + (byte/signed byte/word/signed word/dword/signed dword) 6 [ level#21 current_movedown_slow#69 level_bcd#8 ] ( main:12::play_movement:51::play_move_down:165::play_update_score:276::play_increase_level:318 [ render_screen_show#16 render_screen_render#18 keyboard_events_size#16 play_movement::key_event#0 game_over#10 next_piece_idx#10 lines_bcd#30 score_bcd#30 level#21 current_movedown_slow#69 level_bcd#8 ] ) always clobbers reg byte a reg byte x @@ -19025,10 +19024,10 @@ render_moving: { jmp b1 //SEG330 render_moving::@1 b1: - //SEG331 [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 -- vbuz1_gt_vbuc1_then_la1 - lda #2 - cmp ypos2 - bcc b2 + //SEG331 [132] if((byte) render_moving::ypos2#2>=(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto render_moving::@2 -- vbuz1_ge_vbuc1_then_la1 + lda ypos2 + cmp #2+1 + bcs b2 jmp b7 //SEG332 render_moving::@7 b7: @@ -20088,11 +20087,11 @@ play_update_score: { play_increase_level: { //SEG760 [321] (byte) level#21 ← ++ (byte) level#10 -- vbuz1=_inc_vbuz1 inc level - //SEG761 [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 -- vbuz1_gt_vbuc1_then_la1 + //SEG761 [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 -- vbuz1_ge_vbuc1_then_la1 // Update speed of moving tetrominos down - lda #$1d - cmp level - bcc b1_from_play_increase_level + lda level + cmp #$1d+1 + bcs b1_from_play_increase_level jmp b3 //SEG762 play_increase_level::@3 b3: @@ -22263,6 +22262,7 @@ Removing instruction jmp b1 Removing instruction jmp b1 Removing instruction jmp b2 Succesful ASM optimization Pass5NextJumpElimination +Replacing instruction ldy level with TAY Removing instruction breturn: Removing instruction breturn: Removing instruction breturn: @@ -23607,7 +23607,7 @@ reg byte a [ sprites_irq::ptr#2 ] FINAL ASSEMBLER -Score: 3348891 +Score: 3348890 //SEG0 File Comments // Tetris Game for the Commodore 64 @@ -24427,10 +24427,10 @@ render_moving: { //SEG329 [131] phi (byte) render_moving::ypos2#2 = (byte) render_moving::ypos2#1 [phi:render_moving::@3->render_moving::@1#2] -- register_copy //SEG330 render_moving::@1 b1: - //SEG331 [132] if((byte) render_moving::ypos2#2>(byte/signed byte/word/signed word/dword/signed dword) 2) goto render_moving::@2 -- vbuz1_gt_vbuc1_then_la1 - lda #2 - cmp ypos2 - bcc b2 + //SEG331 [132] if((byte) render_moving::ypos2#2>=(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto render_moving::@2 -- vbuz1_ge_vbuc1_then_la1 + lda ypos2 + cmp #2+1 + bcs b2 //SEG332 render_moving::@7 //SEG333 [133] (byte) render_moving::i#1 ← (byte) render_moving::i#3 + (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuz1=vbuz1_plus_vbuc1 lax i @@ -25330,14 +25330,14 @@ play_update_score: { play_increase_level: { //SEG760 [321] (byte) level#21 ← ++ (byte) level#10 -- vbuz1=_inc_vbuz1 inc level - //SEG761 [322] if((byte) level#21>(byte/signed byte/word/signed word/dword/signed dword) $1d) goto play_increase_level::@1 -- vbuz1_gt_vbuc1_then_la1 + //SEG761 [322] if((byte) level#21>=(byte/signed byte/word/signed word/dword/signed dword) $1d+(byte/signed byte/word/signed word/dword/signed dword) 1) goto play_increase_level::@1 -- vbuz1_ge_vbuc1_then_la1 // Update speed of moving tetrominos down - lda #$1d - cmp level - bcc b3 + lda level + cmp #$1d+1 + bcs b3 //SEG762 play_increase_level::@3 //SEG763 [323] (byte) current_movedown_slow#10 ← *((const byte[]) MOVEDOWN_SLOW_SPEEDS#0 + (byte) level#21) -- vbuz1=pbuc1_derefidx_vbuz2 - ldy level + tay lda MOVEDOWN_SLOW_SPEEDS,y sta current_movedown_slow //SEG764 [324] phi from play_increase_level::@3 to play_increase_level::@1 [phi:play_increase_level::@3->play_increase_level::@1] diff --git a/src/test/ref/const-identification.asm b/src/test/ref/const-identification.asm index 42abf8fdb..64e3997d4 100644 --- a/src/test/ref/const-identification.asm +++ b/src/test/ref/const-identification.asm @@ -24,9 +24,8 @@ line: { b1: jsr plot iny - cpy #x1 + cpy #x1+1 bcc b1 - beq b1 rts } // plot(byte register(Y) x) diff --git a/src/test/ref/const-identification.cfg b/src/test/ref/const-identification.cfg index 9466d263f..6cd8f760d 100644 --- a/src/test/ref/const-identification.cfg +++ b/src/test/ref/const-identification.cfg @@ -31,7 +31,7 @@ line::@1: scope:[line] from line line::@2 to:line::@2 line::@2: scope:[line] from line::@1 [16] (byte) line::x#1 ← ++ (byte) line::x#2 - [17] if((byte) line::x#1<=(const byte) line::x1#0) goto line::@1 + [17] if((byte) line::x#1<(const byte) line::x1#0+(byte/signed byte/word/signed word/dword/signed dword) 1) goto line::@1 to:line::@return line::@return: scope:[line] from line::@2 [18] return diff --git a/src/test/ref/const-identification.log b/src/test/ref/const-identification.log index c8ea472da..1ed3690de 100644 --- a/src/test/ref/const-identification.log +++ b/src/test/ref/const-identification.log @@ -165,6 +165,7 @@ Removing unused block line::@3 Successful SSA optimization Pass2EliminateUnusedBlocks Resolved ranged next value main::i#1 ← ++ main::i#2 to ++ Resolved ranged comparison value if(main::i#1!=rangelast(0,$27)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) $28 +Rewriting conditional comparison if((byte) line::x#1<=(const byte) line::x1#0) goto line::@5 Culled Empty Block (label) main::@5 Culled Empty Block (label) line::@1 Successful SSA optimization Pass2CullEmptyBlocks @@ -238,7 +239,7 @@ line::@1: scope:[line] from line line::@2 to:line::@2 line::@2: scope:[line] from line::@1 [16] (byte) line::x#1 ← ++ (byte) line::x#2 - [17] if((byte) line::x#1<=(const byte) line::x1#0) goto line::@1 + [17] if((byte) line::x#1<(const byte) line::x1#0+(byte/signed byte/word/signed word/dword/signed dword) 1) goto line::@1 to:line::@return line::@return: scope:[line] from line::@2 [18] return @@ -384,10 +385,10 @@ line: { b2: //SEG33 [16] (byte) line::x#1 ← ++ (byte) line::x#2 -- vbuz1=_inc_vbuz1 inc x - //SEG34 [17] if((byte) line::x#1<=(const byte) line::x1#0) goto line::@1 -- vbuz1_le_vbuc1_then_la1 - lda #x1 - cmp x - bcs b1_from_b2 + //SEG34 [17] if((byte) line::x#1<(const byte) line::x1#0+(byte/signed byte/word/signed word/dword/signed dword) 1) goto line::@1 -- vbuz1_lt_vbuc1_then_la1 + lda x + cmp #x1+1 + bcc b1_from_b2 jmp breturn //SEG35 line::@return breturn: @@ -442,7 +443,7 @@ Uplifting [plot] best 4368 combination reg byte y [ plot::x#1 ] reg byte a [ plo Uplifting [main] best 4218 combination reg byte x [ main::i#2 main::i#1 ] Uplifting [] best 4218 combination Attempting to uplift remaining variables inzp ZP_BYTE:3 [ line::x#2 line::x#1 ] -Uplifting [line] best 3268 combination reg byte y [ line::x#2 line::x#1 ] +Uplifting [line] best 3018 combination reg byte y [ line::x#2 line::x#1 ] ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -528,10 +529,9 @@ line: { b2: //SEG33 [16] (byte) line::x#1 ← ++ (byte) line::x#2 -- vbuyy=_inc_vbuyy iny - //SEG34 [17] if((byte) line::x#1<=(const byte) line::x1#0) goto line::@1 -- vbuyy_le_vbuc1_then_la1 - cpy #x1 + //SEG34 [17] if((byte) line::x#1<(const byte) line::x1#0+(byte/signed byte/word/signed word/dword/signed dword) 1) goto line::@1 -- vbuyy_lt_vbuc1_then_la1 + cpy #x1+1 bcc b1_from_b2 - beq b1_from_b2 jmp breturn //SEG35 line::@return breturn: @@ -569,7 +569,6 @@ Succesful ASM optimization Pass5NextJumpElimination Replacing label b1_from_b1 with b1 Replacing label b2_from_b2 with b2 Replacing label b1_from_b2 with b1 -Replacing label b1_from_b2 with b1 Removing instruction b1_from_bbegin: Removing instruction b1: Removing instruction main_from_b1: @@ -637,7 +636,7 @@ reg byte a [ plot::$0 ] FINAL ASSEMBLER -Score: 1963 +Score: 1713 //SEG0 File Comments //SEG1 Basic Upstart @@ -699,10 +698,9 @@ line: { //SEG32 line::@2 //SEG33 [16] (byte) line::x#1 ← ++ (byte) line::x#2 -- vbuyy=_inc_vbuyy iny - //SEG34 [17] if((byte) line::x#1<=(const byte) line::x1#0) goto line::@1 -- vbuyy_le_vbuc1_then_la1 - cpy #x1 + //SEG34 [17] if((byte) line::x#1<(const byte) line::x1#0+(byte/signed byte/word/signed word/dword/signed dword) 1) goto line::@1 -- vbuyy_lt_vbuc1_then_la1 + cpy #x1+1 bcc b1 - beq b1 //SEG35 line::@return //SEG36 [18] return rts diff --git a/src/test/ref/examples/fire/fire.asm b/src/test/ref/examples/fire/fire.asm index ae246ed98..d1deada69 100644 --- a/src/test/ref/examples/fire/fire.asm +++ b/src/test/ref/examples/fire/fire.asm @@ -148,9 +148,8 @@ fire: { adc (buffer),y lsr lsr - cmp #2 + cmp #2+1 bcc b4 - beq b4 sec sbc #3 b4: @@ -236,9 +235,8 @@ makecharset: { clc adc c tax - cpx #$3f + cpx #$3f+1 bcc b6 - beq b6 txa axs #$40 lda #1 diff --git a/src/test/ref/examples/fire/fire.cfg b/src/test/ref/examples/fire/fire.cfg index 033a41e41..cc6879196 100644 --- a/src/test/ref/examples/fire/fire.cfg +++ b/src/test/ref/examples/fire/fire.cfg @@ -89,7 +89,7 @@ fire::@2: scope:[fire] from fire::@1 [44] (byte~) fire::$10 ← (byte~) fire::$9 + *((byte*) fire::buffer#4 + (byte/signed byte/word/signed word/dword/signed dword) $28) [45] (byte~) fire::$11 ← (byte~) fire::$10 + *((byte*) fire::buffer#4 + (byte/signed byte/word/signed word/dword/signed dword) $29) [46] (byte) fire::c#0 ← (byte~) fire::$11 >> (byte/signed byte/word/signed word/dword/signed dword) 2 - [47] if((byte) fire::c#0<=(byte/signed byte/word/signed word/dword/signed dword) 2) goto fire::@4 + [47] if((byte) fire::c#0<(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto fire::@4 to:fire::@5 fire::@5: scope:[fire] from fire::@2 [48] (byte) fire::c#1 ← (byte) fire::c#0 - (byte/signed byte/word/signed word/dword/signed dword) 3 @@ -134,7 +134,7 @@ makecharset::@5: scope:[makecharset] from makecharset::@4 makecharset::@6 [67] (byte) makecharset::ii#2 ← phi( makecharset::@4/(byte/signed byte/word/signed word/dword/signed dword) 0 makecharset::@6/(byte) makecharset::ii#1 ) [67] (byte) makecharset::bc#3 ← phi( makecharset::@4/(byte) makecharset::bc#5 makecharset::@6/(byte) makecharset::bc#6 ) [68] (byte) makecharset::bc#1 ← (byte) makecharset::bc#3 + (byte) makecharset::c#7 - [69] if((byte) makecharset::bc#1<=(byte/signed byte/word/signed word/dword/signed dword) $3f) goto makecharset::@6 + [69] if((byte) makecharset::bc#1<(byte/signed byte/word/signed word/dword/signed dword) $3f+(byte/signed byte/word/signed word/dword/signed dword) 1) goto makecharset::@6 to:makecharset::@7 makecharset::@7: scope:[makecharset] from makecharset::@5 [70] (byte) makecharset::bc#2 ← (byte) makecharset::bc#1 - (byte/signed byte/word/signed word/dword/signed dword) $40 diff --git a/src/test/ref/examples/fire/fire.log b/src/test/ref/examples/fire/fire.log index a9ecd7502..90d19617b 100644 --- a/src/test/ref/examples/fire/fire.log +++ b/src/test/ref/examples/fire/fire.log @@ -1165,6 +1165,8 @@ Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks Resolved ranged next value fillscreen::i#1 ← ++ fillscreen::i#2 to ++ Resolved ranged comparison value if(fillscreen::i#1!=rangelast(0,$3e7)) goto fillscreen::@1 to (word/signed word/dword/signed dword) $3e8 +Rewriting conditional comparison if((byte) fire::c#0<=(byte/signed byte/word/signed word/dword/signed dword) 2) goto fire::@4 +Rewriting conditional comparison if((byte) makecharset::bc#1<=(byte/signed byte/word/signed word/dword/signed dword) $3f) goto makecharset::@8 Culled Empty Block (label) @4 Culled Empty Block (label) @6 Culled Empty Block (label) main::@1 @@ -1447,7 +1449,7 @@ fire::@2: scope:[fire] from fire::@1 [44] (byte~) fire::$10 ← (byte~) fire::$9 + *((byte*) fire::buffer#4 + (byte/signed byte/word/signed word/dword/signed dword) $28) [45] (byte~) fire::$11 ← (byte~) fire::$10 + *((byte*) fire::buffer#4 + (byte/signed byte/word/signed word/dword/signed dword) $29) [46] (byte) fire::c#0 ← (byte~) fire::$11 >> (byte/signed byte/word/signed word/dword/signed dword) 2 - [47] if((byte) fire::c#0<=(byte/signed byte/word/signed word/dword/signed dword) 2) goto fire::@4 + [47] if((byte) fire::c#0<(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto fire::@4 to:fire::@5 fire::@5: scope:[fire] from fire::@2 [48] (byte) fire::c#1 ← (byte) fire::c#0 - (byte/signed byte/word/signed word/dword/signed dword) 3 @@ -1492,7 +1494,7 @@ makecharset::@5: scope:[makecharset] from makecharset::@4 makecharset::@6 [67] (byte) makecharset::ii#2 ← phi( makecharset::@4/(byte/signed byte/word/signed word/dword/signed dword) 0 makecharset::@6/(byte) makecharset::ii#1 ) [67] (byte) makecharset::bc#3 ← phi( makecharset::@4/(byte) makecharset::bc#5 makecharset::@6/(byte) makecharset::bc#6 ) [68] (byte) makecharset::bc#1 ← (byte) makecharset::bc#3 + (byte) makecharset::c#7 - [69] if((byte) makecharset::bc#1<=(byte/signed byte/word/signed word/dword/signed dword) $3f) goto makecharset::@6 + [69] if((byte) makecharset::bc#1<(byte/signed byte/word/signed word/dword/signed dword) $3f+(byte/signed byte/word/signed word/dword/signed dword) 1) goto makecharset::@6 to:makecharset::@7 makecharset::@7: scope:[makecharset] from makecharset::@5 [70] (byte) makecharset::bc#2 ← (byte) makecharset::bc#1 - (byte/signed byte/word/signed word/dword/signed dword) $40 @@ -2172,10 +2174,10 @@ fire: { lsr lsr sta c - //SEG94 [47] if((byte) fire::c#0<=(byte/signed byte/word/signed word/dword/signed dword) 2) goto fire::@4 -- vbuz1_le_vbuc1_then_la1 - lda #2 - cmp c - bcs b4_from_b2 + //SEG94 [47] if((byte) fire::c#0<(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto fire::@4 -- vbuz1_lt_vbuc1_then_la1 + lda c + cmp #2+1 + bcc b4_from_b2 jmp b5 //SEG95 fire::@5 b5: @@ -2357,10 +2359,10 @@ makecharset: { clc adc c sta bc - //SEG150 [69] if((byte) makecharset::bc#1<=(byte/signed byte/word/signed word/dword/signed dword) $3f) goto makecharset::@6 -- vbuz1_le_vbuc1_then_la1 - lda #$3f - cmp bc - bcs b6_from_b5 + //SEG150 [69] if((byte) makecharset::bc#1<(byte/signed byte/word/signed word/dword/signed dword) $3f+(byte/signed byte/word/signed word/dword/signed dword) 1) goto makecharset::@6 -- vbuz1_lt_vbuc1_then_la1 + lda bc + cmp #$3f+1 + bcc b6_from_b5 jmp b7 //SEG151 makecharset::@7 b7: @@ -2650,29 +2652,29 @@ Uplift Scope [sid_rnd_init] Uplift Scope [main] Uplift Scope [] -Uplifting [makecharset] best 128195 combination reg byte x [ makecharset::bc#3 makecharset::bc#5 makecharset::bc#6 makecharset::bc#1 makecharset::bc#2 ] reg byte y [ makecharset::b#2 makecharset::b#3 makecharset::b#1 ] reg byte a [ makecharset::$11 ] reg byte a [ makecharset::$12 ] zp ZP_BYTE:37 [ makecharset::$13 ] zp ZP_BYTE:20 [ makecharset::ii#2 makecharset::ii#1 ] zp ZP_BYTE:18 [ makecharset::i#6 makecharset::i#1 ] zp ZP_WORD:38 [ makecharset::$17 ] zp ZP_WORD:40 [ makecharset::$18 ] zp ZP_WORD:42 [ makecharset::$19 ] zp ZP_BYTE:17 [ makecharset::c#7 makecharset::c#1 ] zp ZP_WORD:13 [ makecharset::font#2 makecharset::font#1 ] zp ZP_WORD:15 [ makecharset::font1#2 makecharset::font1#1 ] +Uplifting [makecharset] best 125695 combination reg byte x [ makecharset::bc#3 makecharset::bc#5 makecharset::bc#6 makecharset::bc#1 makecharset::bc#2 ] reg byte y [ makecharset::b#2 makecharset::b#3 makecharset::b#1 ] reg byte a [ makecharset::$11 ] reg byte a [ makecharset::$12 ] zp ZP_BYTE:37 [ makecharset::$13 ] zp ZP_BYTE:20 [ makecharset::ii#2 makecharset::ii#1 ] zp ZP_BYTE:18 [ makecharset::i#6 makecharset::i#1 ] zp ZP_WORD:38 [ makecharset::$17 ] zp ZP_WORD:40 [ makecharset::$18 ] zp ZP_WORD:42 [ makecharset::$19 ] zp ZP_BYTE:17 [ makecharset::c#7 makecharset::c#1 ] zp ZP_WORD:13 [ makecharset::font#2 makecharset::font#1 ] zp ZP_WORD:15 [ makecharset::font1#2 makecharset::font1#1 ] Limited combination testing to 100 combinations of 15552 possible. -Uplifting [fire] best 125545 combination reg byte a [ fire::c#2 fire::c#0 fire::c#1 ] zp ZP_WORD:4 [ fire::buffer#4 fire::buffer#2 ] zp ZP_WORD:8 [ fire::buffer#10 fire::buffer#3 ] reg byte a [ fire::$18 ] reg byte a [ fire::$19 ] reg byte a [ fire::$20 ] zp ZP_BYTE:31 [ fire::$9 ] zp ZP_BYTE:32 [ fire::$10 ] zp ZP_BYTE:33 [ fire::$11 ] zp ZP_WORD:10 [ fire::screen#10 fire::screen#3 fire::screen#1 ] zp ZP_WORD:6 [ fire::screen#4 fire::screen#11 fire::screen#2 ] zp ZP_WORD:2 [ fire::screen#0 ] +Uplifting [fire] best 122795 combination reg byte a [ fire::c#2 fire::c#0 fire::c#1 ] zp ZP_WORD:4 [ fire::buffer#4 fire::buffer#2 ] zp ZP_WORD:8 [ fire::buffer#10 fire::buffer#3 ] reg byte a [ fire::$18 ] reg byte a [ fire::$19 ] reg byte a [ fire::$20 ] zp ZP_BYTE:31 [ fire::$9 ] zp ZP_BYTE:32 [ fire::$10 ] zp ZP_BYTE:33 [ fire::$11 ] zp ZP_WORD:10 [ fire::screen#10 fire::screen#3 fire::screen#1 ] zp ZP_WORD:6 [ fire::screen#4 fire::screen#11 fire::screen#2 ] zp ZP_WORD:2 [ fire::screen#0 ] Limited combination testing to 100 combinations of 16384 possible. -Uplifting [sid_rnd] best 124642 combination reg byte a [ sid_rnd::return#2 ] reg byte a [ sid_rnd::return#0 ] -Uplifting [fillscreen] best 124620 combination zp ZP_WORD:23 [ fillscreen::screen#5 fillscreen::screen#6 fillscreen::screen#4 ] zp ZP_WORD:25 [ fillscreen::i#2 fillscreen::i#1 ] reg byte x [ fillscreen::fill#5 ] -Uplifting [sid_rnd_init] best 124620 combination -Uplifting [main] best 124620 combination -Uplifting [] best 124620 combination +Uplifting [sid_rnd] best 121892 combination reg byte a [ sid_rnd::return#2 ] reg byte a [ sid_rnd::return#0 ] +Uplifting [fillscreen] best 121870 combination zp ZP_WORD:23 [ fillscreen::screen#5 fillscreen::screen#6 fillscreen::screen#4 ] zp ZP_WORD:25 [ fillscreen::i#2 fillscreen::i#1 ] reg byte x [ fillscreen::fill#5 ] +Uplifting [sid_rnd_init] best 121870 combination +Uplifting [main] best 121870 combination +Uplifting [] best 121870 combination Attempting to uplift remaining variables inzp ZP_BYTE:37 [ makecharset::$13 ] -Uplifting [makecharset] best 124620 combination zp ZP_BYTE:37 [ makecharset::$13 ] +Uplifting [makecharset] best 121870 combination zp ZP_BYTE:37 [ makecharset::$13 ] Attempting to uplift remaining variables inzp ZP_BYTE:20 [ makecharset::ii#2 makecharset::ii#1 ] -Uplifting [makecharset] best 124620 combination zp ZP_BYTE:20 [ makecharset::ii#2 makecharset::ii#1 ] +Uplifting [makecharset] best 121870 combination zp ZP_BYTE:20 [ makecharset::ii#2 makecharset::ii#1 ] Attempting to uplift remaining variables inzp ZP_BYTE:18 [ makecharset::i#6 makecharset::i#1 ] -Uplifting [makecharset] best 124620 combination zp ZP_BYTE:18 [ makecharset::i#6 makecharset::i#1 ] +Uplifting [makecharset] best 121870 combination zp ZP_BYTE:18 [ makecharset::i#6 makecharset::i#1 ] Attempting to uplift remaining variables inzp ZP_BYTE:31 [ fire::$9 ] -Uplifting [fire] best 124020 combination reg byte a [ fire::$9 ] +Uplifting [fire] best 121270 combination reg byte a [ fire::$9 ] Attempting to uplift remaining variables inzp ZP_BYTE:32 [ fire::$10 ] -Uplifting [fire] best 123420 combination reg byte a [ fire::$10 ] +Uplifting [fire] best 120670 combination reg byte a [ fire::$10 ] Attempting to uplift remaining variables inzp ZP_BYTE:33 [ fire::$11 ] -Uplifting [fire] best 122820 combination reg byte a [ fire::$11 ] +Uplifting [fire] best 120070 combination reg byte a [ fire::$11 ] Attempting to uplift remaining variables inzp ZP_BYTE:17 [ makecharset::c#7 makecharset::c#1 ] -Uplifting [makecharset] best 122820 combination zp ZP_BYTE:17 [ makecharset::c#7 makecharset::c#1 ] +Uplifting [makecharset] best 120070 combination zp ZP_BYTE:17 [ makecharset::c#7 makecharset::c#1 ] Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ fire::screen#0 ] ] with [ zp ZP_WORD:10 [ fire::screen#10 fire::screen#3 fire::screen#1 ] ] - score: 1 Coalescing zero page register with common assignment [ zp ZP_WORD:38 [ makecharset::$17 ] ] with [ zp ZP_WORD:40 [ makecharset::$18 ] ] - score: 1 Coalescing zero page register with common assignment [ zp ZP_WORD:38 [ makecharset::$17 makecharset::$18 ] ] with [ zp ZP_WORD:42 [ makecharset::$19 ] ] - score: 1 @@ -2992,10 +2994,9 @@ fire: { //SEG93 [46] (byte) fire::c#0 ← (byte~) fire::$11 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuaa_ror_2 lsr lsr - //SEG94 [47] if((byte) fire::c#0<=(byte/signed byte/word/signed word/dword/signed dword) 2) goto fire::@4 -- vbuaa_le_vbuc1_then_la1 - cmp #2 + //SEG94 [47] if((byte) fire::c#0<(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto fire::@4 -- vbuaa_lt_vbuc1_then_la1 + cmp #2+1 bcc b4_from_b2 - beq b4_from_b2 jmp b5 //SEG95 fire::@5 b5: @@ -3166,10 +3167,9 @@ makecharset: { clc adc c tax - //SEG150 [69] if((byte) makecharset::bc#1<=(byte/signed byte/word/signed word/dword/signed dword) $3f) goto makecharset::@6 -- vbuxx_le_vbuc1_then_la1 - cpx #$3f + //SEG150 [69] if((byte) makecharset::bc#1<(byte/signed byte/word/signed word/dword/signed dword) $3f+(byte/signed byte/word/signed word/dword/signed dword) 1) goto makecharset::@6 -- vbuxx_lt_vbuc1_then_la1 + cpx #$3f+1 bcc b6_from_b5 - beq b6_from_b5 jmp b7 //SEG151 makecharset::@7 b7: @@ -3382,13 +3382,11 @@ Replacing label b1_from_b3 with b1 Replacing label b7_from_b6 with b7 Replacing label b7_from_b6 with b7 Replacing label b4_from_b2 with b4 -Replacing label b4_from_b2 with b4 Replacing label b1_from_b1 with b1 Replacing label b1_from_b1 with b1 Replacing label b2_from_b2 with b2 Replacing label b2_from_b2 with b2 Replacing label b6_from_b5 with b6 -Replacing label b6_from_b5 with b6 Replacing label b5_from_b6 with b5 Replacing label b4_from_b8 with b4 Replacing label b3_from_b9 with b3 @@ -3744,7 +3742,7 @@ zp ZP_BYTE:11 [ makecharset::$13 ] FINAL ASSEMBLER -Score: 102365 +Score: 99615 //SEG0 File Comments // A KickC version of the fire routine from the CC65 samples @@ -3990,10 +3988,9 @@ fire: { //SEG93 [46] (byte) fire::c#0 ← (byte~) fire::$11 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuaa_ror_2 lsr lsr - //SEG94 [47] if((byte) fire::c#0<=(byte/signed byte/word/signed word/dword/signed dword) 2) goto fire::@4 -- vbuaa_le_vbuc1_then_la1 - cmp #2 + //SEG94 [47] if((byte) fire::c#0<(byte/signed byte/word/signed word/dword/signed dword) 2+(byte/signed byte/word/signed word/dword/signed dword) 1) goto fire::@4 -- vbuaa_lt_vbuc1_then_la1 + cmp #2+1 bcc b4 - beq b4 //SEG95 fire::@5 //SEG96 [48] (byte) fire::c#1 ← (byte) fire::c#0 - (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuaa_minus_vbuc1 sec @@ -4134,10 +4131,9 @@ makecharset: { clc adc c tax - //SEG150 [69] if((byte) makecharset::bc#1<=(byte/signed byte/word/signed word/dword/signed dword) $3f) goto makecharset::@6 -- vbuxx_le_vbuc1_then_la1 - cpx #$3f + //SEG150 [69] if((byte) makecharset::bc#1<(byte/signed byte/word/signed word/dword/signed dword) $3f+(byte/signed byte/word/signed word/dword/signed dword) 1) goto makecharset::@6 -- vbuxx_lt_vbuc1_then_la1 + cpx #$3f+1 bcc b6 - beq b6 //SEG151 makecharset::@7 //SEG152 [70] (byte) makecharset::bc#2 ← (byte) makecharset::bc#1 - (byte/signed byte/word/signed word/dword/signed dword) $40 -- vbuxx=vbuxx_minus_vbuc1 txa diff --git a/src/test/ref/irq-volatile-bool-problem.asm b/src/test/ref/irq-volatile-bool-problem.asm index 8d5709f8d..894235e1a 100644 --- a/src/test/ref/irq-volatile-bool-problem.asm +++ b/src/test/ref/irq-volatile-bool-problem.asm @@ -51,9 +51,8 @@ irq: { lda #IRQ_RASTER sta IRQ_STATUS lda RASTER - cmp #$32 + cmp #$32+1 bcc b1 - beq b1 lda #0 sta framedone b1: diff --git a/src/test/ref/irq-volatile-bool-problem.cfg b/src/test/ref/irq-volatile-bool-problem.cfg index 4dc27e341..5346c42b7 100644 --- a/src/test/ref/irq-volatile-bool-problem.cfg +++ b/src/test/ref/irq-volatile-bool-problem.cfg @@ -28,7 +28,7 @@ main::@2: scope:[main] from main::@1 irq: scope:[irq] from [14] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 - [16] if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 + [16] if(*((const byte*) RASTER#0)<(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto irq::@1 to:irq::@2 irq::@2: scope:[irq] from irq [17] (bool) framedone#3 ← false diff --git a/src/test/ref/irq-volatile-bool-problem.log b/src/test/ref/irq-volatile-bool-problem.log index faeb701b4..8e41119bd 100644 --- a/src/test/ref/irq-volatile-bool-problem.log +++ b/src/test/ref/irq-volatile-bool-problem.log @@ -168,6 +168,7 @@ Successful SSA optimization Pass2ConstantIfs Successful SSA optimization PassNEliminateUnusedVars Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks +Rewriting conditional comparison if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 Culled Empty Block (label) main::@4 Culled Empty Block (label) @3 Successful SSA optimization Pass2CullEmptyBlocks @@ -220,7 +221,7 @@ main::@2: scope:[main] from main::@1 irq: scope:[irq] from [14] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 - [16] if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 + [16] if(*((const byte*) RASTER#0)<(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto irq::@1 to:irq::@2 irq::@2: scope:[irq] from irq [17] (bool) framedone#3 ← false @@ -347,11 +348,10 @@ irq: { //SEG26 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 lda #IRQ_RASTER sta IRQ_STATUS - //SEG27 [16] if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 -- _deref_pbuc1_le_vbuc2_then_la1 + //SEG27 [16] if(*((const byte*) RASTER#0)<(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto irq::@1 -- _deref_pbuc1_lt_vbuc2_then_la1 lda RASTER - cmp #$32 + cmp #$32+1 bcc b1 - beq b1 jmp b2 //SEG28 irq::@2 b2: @@ -380,7 +380,7 @@ Statement [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void( Statement [12] if(*((const byte*) RASTER#0)>=(byte/signed byte/word/signed word/dword/signed dword) $14) goto main::@1 [ ] ( main:3 [ ] ) always clobbers reg byte a Statement [13] (bool) framedone#0 ← true [ ] ( main:3 [ ] ) always clobbers reg byte a Statement [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( [ ] ) always clobbers reg byte a -Statement [16] if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 [ ] ( [ ] ) always clobbers reg byte a +Statement [16] if(*((const byte*) RASTER#0)<(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto irq::@1 [ ] ( [ ] ) always clobbers reg byte a Statement [17] (bool) framedone#3 ← false [ ] ( [ ] ) always clobbers reg byte a Potential registers zp ZP_BOOL:2 [ framedone#0 framedone#3 framedone#11 ] : zp ZP_BOOL:2 , @@ -389,9 +389,9 @@ Uplift Scope [] 150: zp ZP_BOOL:2 [ framedone#0 framedone#3 framedone#11 ] Uplift Scope [main] Uplift Scope [irq] -Uplifting [] best 1370 combination zp ZP_BOOL:2 [ framedone#0 framedone#3 framedone#11 ] -Uplifting [main] best 1370 combination -Uplifting [irq] best 1370 combination +Uplifting [] best 1367 combination zp ZP_BOOL:2 [ framedone#0 framedone#3 framedone#11 ] +Uplifting [main] best 1367 combination +Uplifting [irq] best 1367 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -483,11 +483,10 @@ irq: { //SEG26 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 lda #IRQ_RASTER sta IRQ_STATUS - //SEG27 [16] if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 -- _deref_pbuc1_le_vbuc2_then_la1 + //SEG27 [16] if(*((const byte*) RASTER#0)<(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto irq::@1 -- _deref_pbuc1_lt_vbuc2_then_la1 lda RASTER - cmp #$32 + cmp #$32+1 bcc b1 - beq b1 jmp b2 //SEG28 irq::@2 b2: @@ -568,7 +567,7 @@ zp ZP_BOOL:2 [ framedone#0 framedone#3 framedone#11 ] FINAL ASSEMBLER -Score: 1028 +Score: 1025 //SEG0 File Comments // Illustrates a problem where a volatile bool modified at the end of an IRQ is not stored properly @@ -649,11 +648,10 @@ irq: { //SEG26 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 lda #IRQ_RASTER sta IRQ_STATUS - //SEG27 [16] if(*((const byte*) RASTER#0)<=(byte/signed byte/word/signed word/dword/signed dword) $32) goto irq::@1 -- _deref_pbuc1_le_vbuc2_then_la1 + //SEG27 [16] if(*((const byte*) RASTER#0)<(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto irq::@1 -- _deref_pbuc1_lt_vbuc2_then_la1 lda RASTER - cmp #$32 + cmp #$32+1 bcc b1 - beq b1 //SEG28 irq::@2 //SEG29 [17] (bool) framedone#3 ← false -- vboz1=vboc1 lda #0 diff --git a/src/test/ref/longbranch-interrupt-problem.asm b/src/test/ref/longbranch-interrupt-problem.asm index 1f965f36c..a1b0376f2 100644 --- a/src/test/ref/longbranch-interrupt-problem.asm +++ b/src/test/ref/longbranch-interrupt-problem.asm @@ -16,9 +16,9 @@ main: { lda #>irq sta KERNEL_IRQ+1 b2: - lda #$a - cmp col - bcs b2 + lda col + cmp #$a+1 + bcc b2 lda #0 sta col jmp b2 diff --git a/src/test/ref/longbranch-interrupt-problem.cfg b/src/test/ref/longbranch-interrupt-problem.cfg index 5ad552574..97c92a0a4 100644 --- a/src/test/ref/longbranch-interrupt-problem.cfg +++ b/src/test/ref/longbranch-interrupt-problem.cfg @@ -14,7 +14,7 @@ main::@1: scope:[main] from main main::@2 main::@3 [5] (byte) col#12 ← phi( main/(byte) col#0 main::@3/(byte) col#1 ) to:main::@2 main::@2: scope:[main] from main::@1 - [6] if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 + [6] if((byte) col#12<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 diff --git a/src/test/ref/longbranch-interrupt-problem.log b/src/test/ref/longbranch-interrupt-problem.log index 34e719e62..bdc6e867a 100644 --- a/src/test/ref/longbranch-interrupt-problem.log +++ b/src/test/ref/longbranch-interrupt-problem.log @@ -132,6 +132,7 @@ Successful SSA optimization Pass2ConstantIfs Successful SSA optimization PassNEliminateUnusedVars Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks +Rewriting conditional comparison if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@4 Culled Empty Block (label) main::@4 Culled Empty Block (label) irq::@1 Culled Empty Block (label) @3 @@ -170,7 +171,7 @@ main::@1: scope:[main] from main main::@2 main::@3 [5] (byte) col#12 ← phi( main/(byte) col#0 main::@3/(byte) col#1 ) to:main::@2 main::@2: scope:[main] from main::@1 - [6] if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 + [6] if((byte) col#12<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 @@ -254,10 +255,10 @@ main: { jmp b2 //SEG16 main::@2 b2: - //SEG17 [6] if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 -- vbuz1_le_vbuc1_then_la1 - lda #$a - cmp col - bcs b1_from_b2 + //SEG17 [6] if((byte) col#12<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 -- vbuz1_lt_vbuc1_then_la1 + lda col + cmp #$a+1 + bcc b1_from_b2 jmp b3 //SEG18 main::@3 b3: @@ -293,7 +294,7 @@ irq: { REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] (byte) col#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ col#0 ] ( ) always clobbers reg byte a Statement [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ col#0 ] ( main:2 [ col#0 ] ) always clobbers reg byte a -Statement [6] if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [6] if((byte) col#12<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ col#1 ] ( main:2 [ col#1 ] ) always clobbers reg byte a Statement asm { lda$dc0d } always clobbers reg byte a Statement [9] *((const byte*) BGCOL#0) ← (byte) col#0 [ col#0 ] ( [ col#0 ] ) always clobbers reg byte a @@ -359,10 +360,10 @@ main: { jmp b2 //SEG16 main::@2 b2: - //SEG17 [6] if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 -- vbuz1_le_vbuc1_then_la1 - lda #$a - cmp col - bcs b1_from_b2 + //SEG17 [6] if((byte) col#12<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 -- vbuz1_lt_vbuc1_then_la1 + lda col + cmp #$a+1 + bcc b1_from_b2 jmp b3 //SEG18 main::@3 b3: @@ -494,10 +495,10 @@ main: { //SEG15 main::@1 //SEG16 main::@2 b2: - //SEG17 [6] if((byte) col#12<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 -- vbuz1_le_vbuc1_then_la1 - lda #$a - cmp col - bcs b2 + //SEG17 [6] if((byte) col#12<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 -- vbuz1_lt_vbuc1_then_la1 + lda col + cmp #$a+1 + bcc b2 //SEG18 main::@3 //SEG19 [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 lda #0 diff --git a/src/test/ref/loopmin.asm b/src/test/ref/loopmin.asm index 3bbc86903..4e5845cce 100644 --- a/src/test/ref/loopmin.asm +++ b/src/test/ref/loopmin.asm @@ -5,9 +5,8 @@ main: { lda #0 ldx #$a b1: - cpx #5 + cpx #5+1 bcc b2 - beq b2 stx $ff clc adc $ff diff --git a/src/test/ref/loopmin.cfg b/src/test/ref/loopmin.cfg index fbc9bbc1c..7876a5a4c 100644 --- a/src/test/ref/loopmin.cfg +++ b/src/test/ref/loopmin.cfg @@ -13,7 +13,7 @@ main: scope:[main] from @1 main::@1: scope:[main] from main main::@2 [5] (byte) main::s#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@2/(byte) main::s#4 ) [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) $a main::@2/(byte) main::i#1 ) - [6] if((byte) main::i#2<=(byte/signed byte/word/signed word/dword/signed dword) 5) goto main::@2 + [6] if((byte) main::i#2<(byte/signed byte/word/signed word/dword/signed dword) 5+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@2 to:main::@3 main::@3: scope:[main] from main::@1 [7] (byte) main::s#1 ← (byte) main::s#2 + (byte) main::i#2 diff --git a/src/test/ref/loopmin.log b/src/test/ref/loopmin.log index b14e0cab9..c5da8c16e 100644 --- a/src/test/ref/loopmin.log +++ b/src/test/ref/loopmin.log @@ -79,6 +79,7 @@ Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte) main::i#0 = $a Constant (const byte) main::s#0 = 0 Successful SSA optimization Pass2ConstantIdentification +Rewriting conditional comparison if((byte) main::i#2<=(byte/signed byte/word/signed word/dword/signed dword) 5) goto main::@2 Inlining constant with var siblings (const byte) main::i#0 Inlining constant with var siblings (const byte) main::s#0 Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) $a @@ -122,7 +123,7 @@ main: scope:[main] from @1 main::@1: scope:[main] from main main::@2 [5] (byte) main::s#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@2/(byte) main::s#4 ) [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) $a main::@2/(byte) main::i#1 ) - [6] if((byte) main::i#2<=(byte/signed byte/word/signed word/dword/signed dword) 5) goto main::@2 + [6] if((byte) main::i#2<(byte/signed byte/word/signed word/dword/signed dword) 5+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@2 to:main::@3 main::@3: scope:[main] from main::@1 [7] (byte) main::s#1 ← (byte) main::s#2 + (byte) main::i#2 @@ -199,10 +200,10 @@ main: { jmp b1 //SEG17 main::@1 b1: - //SEG18 [6] if((byte) main::i#2<=(byte/signed byte/word/signed word/dword/signed dword) 5) goto main::@2 -- vbuz1_le_vbuc1_then_la1 - lda #5 - cmp i - bcs b2_from_b1 + //SEG18 [6] if((byte) main::i#2<(byte/signed byte/word/signed word/dword/signed dword) 5+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda i + cmp #5+1 + bcc b2_from_b1 jmp b3 //SEG19 main::@3 b3: @@ -241,8 +242,8 @@ REGISTER UPLIFT SCOPES Uplift Scope [main] 49.5: zp ZP_BYTE:3 [ main::s#2 main::s#4 main::s#1 ] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] Uplift Scope [] -Uplifting [main] best 423 combination reg byte a [ main::s#2 main::s#4 main::s#1 ] reg byte x [ main::i#2 main::i#1 ] -Uplifting [] best 423 combination +Uplifting [main] best 398 combination reg byte a [ main::s#2 main::s#4 main::s#1 ] reg byte x [ main::i#2 main::i#1 ] +Uplifting [] best 398 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -283,10 +284,9 @@ main: { jmp b1 //SEG17 main::@1 b1: - //SEG18 [6] if((byte) main::i#2<=(byte/signed byte/word/signed word/dword/signed dword) 5) goto main::@2 -- vbuxx_le_vbuc1_then_la1 - cpx #5 + //SEG18 [6] if((byte) main::i#2<(byte/signed byte/word/signed word/dword/signed dword) 5+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@2 -- vbuxx_lt_vbuc1_then_la1 + cpx #5+1 bcc b2_from_b1 - beq b2_from_b1 jmp b3 //SEG19 main::@3 b3: @@ -322,7 +322,6 @@ Removing instruction jmp b2 Removing instruction jmp breturn Succesful ASM optimization Pass5NextJumpElimination Replacing label b2_from_b1 with b2 -Replacing label b2_from_b1 with b2 Replacing label b1_from_b2 with b1 Removing instruction b1_from_bbegin: Removing instruction b1: @@ -367,7 +366,7 @@ reg byte a [ main::s#2 main::s#4 main::s#1 ] FINAL ASSEMBLER -Score: 261 +Score: 236 //SEG0 File Comments //SEG1 Basic Upstart @@ -394,10 +393,9 @@ main: { //SEG16 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#1] -- register_copy //SEG17 main::@1 b1: - //SEG18 [6] if((byte) main::i#2<=(byte/signed byte/word/signed word/dword/signed dword) 5) goto main::@2 -- vbuxx_le_vbuc1_then_la1 - cpx #5 + //SEG18 [6] if((byte) main::i#2<(byte/signed byte/word/signed word/dword/signed dword) 5+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@2 -- vbuxx_lt_vbuc1_then_la1 + cpx #5+1 bcc b2 - beq b2 //SEG19 main::@3 //SEG20 [7] (byte) main::s#1 ← (byte) main::s#2 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx stx $ff diff --git a/src/test/ref/loopsplit.asm b/src/test/ref/loopsplit.asm index 0fa7b7f8a..66c597c86 100644 --- a/src/test/ref/loopsplit.asm +++ b/src/test/ref/loopsplit.asm @@ -2,22 +2,19 @@ :BasicUpstart(main) .pc = $80d "Program" main: { - ldx #0 - lda #$64 + ldy #0 + ldx #$64 b1: - sec - sbc #1 - cmp #0 + dex + cpx #0 bne b2 rts b2: - cmp #$32 - beq !+ + cpx #$32+1 bcs b3 - !: - dex + dey jmp b1 b3: - inx + iny jmp b1 } diff --git a/src/test/ref/loopsplit.cfg b/src/test/ref/loopsplit.cfg index ec31edbd6..58d20549b 100644 --- a/src/test/ref/loopsplit.cfg +++ b/src/test/ref/loopsplit.cfg @@ -20,7 +20,7 @@ main::@return: scope:[main] from main::@1 [8] return to:@return main::@2: scope:[main] from main::@1 - [9] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) $32) goto main::@3 + [9] if((byte) main::i#1>=(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 to:main::@4 main::@4: scope:[main] from main::@2 [10] (byte) main::s#2 ← -- (byte) main::s#3 diff --git a/src/test/ref/loopsplit.log b/src/test/ref/loopsplit.log index 9432ce03d..28d2a8f08 100644 --- a/src/test/ref/loopsplit.log +++ b/src/test/ref/loopsplit.log @@ -79,6 +79,7 @@ Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte) main::i#0 = $64 Constant (const byte) main::s#0 = 0 Successful SSA optimization Pass2ConstantIdentification +Rewriting conditional comparison if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) $32) goto main::@4 Inlining constant with var siblings (const byte) main::i#0 Inlining constant with var siblings (const byte) main::s#0 Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) $64 @@ -127,7 +128,7 @@ main::@return: scope:[main] from main::@1 [8] return to:@return main::@2: scope:[main] from main::@1 - [9] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) $32) goto main::@3 + [9] if((byte) main::i#1>=(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 to:main::@4 main::@4: scope:[main] from main::@2 [10] (byte) main::s#2 ← -- (byte) main::s#3 @@ -206,10 +207,10 @@ main: { rts //SEG19 main::@2 b2: - //SEG20 [9] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) $32) goto main::@3 -- vbuz1_gt_vbuc1_then_la1 - lda #$32 - cmp i - bcc b3 + //SEG20 [9] if((byte) main::i#1>=(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 -- vbuz1_ge_vbuc1_then_la1 + lda i + cmp #$32+1 + bcs b3 jmp b4 //SEG21 main::@4 b4: @@ -236,8 +237,8 @@ REGISTER UPLIFT SCOPES Uplift Scope [main] 55: zp ZP_BYTE:3 [ main::s#3 main::s#1 main::s#2 ] 44: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] Uplift Scope [] -Uplifting [main] best 403 combination reg byte x [ main::s#3 main::s#1 main::s#2 ] reg byte a [ main::i#2 main::i#1 ] -Uplifting [] best 403 combination +Uplifting [main] best 358 combination reg byte y [ main::s#3 main::s#1 main::s#2 ] reg byte x [ main::i#2 main::i#1 ] +Uplifting [] best 358 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -266,18 +267,17 @@ bend: main: { //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] b1_from_main: - //SEG12 [5] phi (byte) main::s#3 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 - ldx #0 - //SEG13 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) $64 [phi:main->main::@1#1] -- vbuaa=vbuc1 - lda #$64 + //SEG12 [5] phi (byte) main::s#3 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1 + ldy #0 + //SEG13 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) $64 [phi:main->main::@1#1] -- vbuxx=vbuc1 + ldx #$64 jmp b1 //SEG14 main::@1 b1: - //SEG15 [6] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuaa=_dec_vbuaa - sec - sbc #1 - //SEG16 [7] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2 -- vbuaa_gt_0_then_la1 - cmp #0 + //SEG15 [6] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuxx=_dec_vbuxx + dex + //SEG16 [7] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2 -- vbuxx_gt_0_then_la1 + cpx #0 bne b2 jmp breturn //SEG17 main::@return @@ -286,16 +286,14 @@ main: { rts //SEG19 main::@2 b2: - //SEG20 [9] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) $32) goto main::@3 -- vbuaa_gt_vbuc1_then_la1 - cmp #$32 - beq !+ + //SEG20 [9] if((byte) main::i#1>=(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 -- vbuxx_ge_vbuc1_then_la1 + cpx #$32+1 bcs b3 - !: jmp b4 //SEG21 main::@4 b4: - //SEG22 [10] (byte) main::s#2 ← -- (byte) main::s#3 -- vbuxx=_dec_vbuxx - dex + //SEG22 [10] (byte) main::s#2 ← -- (byte) main::s#3 -- vbuyy=_dec_vbuyy + dey //SEG23 [5] phi from main::@3 main::@4 to main::@1 [phi:main::@3/main::@4->main::@1] b1_from_b3: b1_from_b4: @@ -304,8 +302,8 @@ main: { jmp b1 //SEG26 main::@3 b3: - //SEG27 [11] (byte) main::s#1 ← ++ (byte) main::s#3 -- vbuxx=_inc_vbuxx - inx + //SEG27 [11] (byte) main::s#1 ← ++ (byte) main::s#3 -- vbuyy=_inc_vbuyy + iny jmp b1_from_b3 } @@ -350,19 +348,19 @@ FINAL SYMBOL TABLE (label) main::@4 (label) main::@return (byte) main::i -(byte) main::i#1 reg byte a 11.0 -(byte) main::i#2 reg byte a 33.0 +(byte) main::i#1 reg byte x 11.0 +(byte) main::i#2 reg byte x 33.0 (byte) main::s -(byte) main::s#1 reg byte x 22.0 -(byte) main::s#2 reg byte x 22.0 -(byte) main::s#3 reg byte x 11.0 +(byte) main::s#1 reg byte y 22.0 +(byte) main::s#2 reg byte y 22.0 +(byte) main::s#3 reg byte y 11.0 -reg byte a [ main::i#2 main::i#1 ] -reg byte x [ main::s#3 main::s#1 main::s#2 ] +reg byte x [ main::i#2 main::i#1 ] +reg byte y [ main::s#3 main::s#1 main::s#2 ] FINAL ASSEMBLER -Score: 301 +Score: 256 //SEG0 File Comments //SEG1 Basic Upstart @@ -380,39 +378,36 @@ Score: 301 //SEG10 main main: { //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] - //SEG12 [5] phi (byte) main::s#3 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 - ldx #0 - //SEG13 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) $64 [phi:main->main::@1#1] -- vbuaa=vbuc1 - lda #$64 + //SEG12 [5] phi (byte) main::s#3 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1 + ldy #0 + //SEG13 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) $64 [phi:main->main::@1#1] -- vbuxx=vbuc1 + ldx #$64 //SEG14 main::@1 b1: - //SEG15 [6] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuaa=_dec_vbuaa - sec - sbc #1 - //SEG16 [7] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2 -- vbuaa_gt_0_then_la1 - cmp #0 + //SEG15 [6] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuxx=_dec_vbuxx + dex + //SEG16 [7] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@2 -- vbuxx_gt_0_then_la1 + cpx #0 bne b2 //SEG17 main::@return //SEG18 [8] return rts //SEG19 main::@2 b2: - //SEG20 [9] if((byte) main::i#1>(byte/signed byte/word/signed word/dword/signed dword) $32) goto main::@3 -- vbuaa_gt_vbuc1_then_la1 - cmp #$32 - beq !+ + //SEG20 [9] if((byte) main::i#1>=(byte/signed byte/word/signed word/dword/signed dword) $32+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@3 -- vbuxx_ge_vbuc1_then_la1 + cpx #$32+1 bcs b3 - !: //SEG21 main::@4 - //SEG22 [10] (byte) main::s#2 ← -- (byte) main::s#3 -- vbuxx=_dec_vbuxx - dex + //SEG22 [10] (byte) main::s#2 ← -- (byte) main::s#3 -- vbuyy=_dec_vbuyy + dey //SEG23 [5] phi from main::@3 main::@4 to main::@1 [phi:main::@3/main::@4->main::@1] //SEG24 [5] phi (byte) main::s#3 = (byte) main::s#1 [phi:main::@3/main::@4->main::@1#0] -- register_copy //SEG25 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@3/main::@4->main::@1#1] -- register_copy jmp b1 //SEG26 main::@3 b3: - //SEG27 [11] (byte) main::s#1 ← ++ (byte) main::s#3 -- vbuxx=_inc_vbuxx - inx + //SEG27 [11] (byte) main::s#1 ← ++ (byte) main::s#3 -- vbuyy=_inc_vbuyy + iny jmp b1 } diff --git a/src/test/ref/loopsplit.sym b/src/test/ref/loopsplit.sym index 632bd040a..daaa0f3f7 100644 --- a/src/test/ref/loopsplit.sym +++ b/src/test/ref/loopsplit.sym @@ -8,12 +8,12 @@ (label) main::@4 (label) main::@return (byte) main::i -(byte) main::i#1 reg byte a 11.0 -(byte) main::i#2 reg byte a 33.0 +(byte) main::i#1 reg byte x 11.0 +(byte) main::i#2 reg byte x 33.0 (byte) main::s -(byte) main::s#1 reg byte x 22.0 -(byte) main::s#2 reg byte x 22.0 -(byte) main::s#3 reg byte x 11.0 +(byte) main::s#1 reg byte y 22.0 +(byte) main::s#2 reg byte y 22.0 +(byte) main::s#3 reg byte y 11.0 -reg byte a [ main::i#2 main::i#1 ] -reg byte x [ main::s#3 main::s#1 main::s#2 ] +reg byte x [ main::i#2 main::i#1 ] +reg byte y [ main::s#3 main::s#1 main::s#2 ] diff --git a/src/test/ref/roll-sprite-msb.asm b/src/test/ref/roll-sprite-msb.asm index 80b22ddde..8ef6b1c41 100644 --- a/src/test/ref/roll-sprite-msb.asm +++ b/src/test/ref/roll-sprite-msb.asm @@ -43,10 +43,11 @@ position_sprite: { lda x sta SPRITES_XPOS,y lda x+1 + cmp #>$ff+1 + bcc !+ bne b1 lda x - cmp #$ff - beq !+ + cmp #<$ff+1 bcs b1 !: lda #1 diff --git a/src/test/ref/roll-sprite-msb.cfg b/src/test/ref/roll-sprite-msb.cfg index 5e2d263fe..bb1524341 100644 --- a/src/test/ref/roll-sprite-msb.cfg +++ b/src/test/ref/roll-sprite-msb.cfg @@ -31,7 +31,7 @@ position_sprite: scope:[position_sprite] from main::@1 [15] (byte~) position_sprite::$1 ← (byte) position_sprite::spriteno#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [16] (byte~) position_sprite::$2 ← < (word) position_sprite::x#0 [17] *((const byte*) SPRITES_XPOS#0 + (byte~) position_sprite::$1) ← (byte~) position_sprite::$2 - [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 + [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 to:position_sprite::@2 position_sprite::@2: scope:[position_sprite] from position_sprite [19] (byte/signed byte/word/signed word/dword/signed dword~) position_sprite::$4 ← (byte/signed byte/word/signed word/dword/signed dword) 1 << (byte) position_sprite::spriteno#0 diff --git a/src/test/ref/roll-sprite-msb.log b/src/test/ref/roll-sprite-msb.log index 758573637..3e6ecf52d 100644 --- a/src/test/ref/roll-sprite-msb.log +++ b/src/test/ref/roll-sprite-msb.log @@ -438,6 +438,7 @@ Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization PassNEliminateUnusedVars Resolved ranged next value main::s#1 ← ++ main::s#2 to ++ Resolved ranged comparison value if(main::s#1!=rangelast(0,7)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 8 +Rewriting conditional comparison if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 Inlining constant with var siblings (const word) main::xpos#0 Inlining constant with var siblings (const byte) main::s#0 Constant inlined main::xpos#0 = (byte/word/signed word/dword/signed dword) $c8 @@ -499,7 +500,7 @@ position_sprite: scope:[position_sprite] from main::@1 [15] (byte~) position_sprite::$1 ← (byte) position_sprite::spriteno#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [16] (byte~) position_sprite::$2 ← < (word) position_sprite::x#0 [17] *((const byte*) SPRITES_XPOS#0 + (byte~) position_sprite::$1) ← (byte~) position_sprite::$2 - [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 + [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 to:position_sprite::@2 position_sprite::@2: scope:[position_sprite] from position_sprite [19] (byte/signed byte/word/signed word/dword/signed dword~) position_sprite::$4 ← (byte/signed byte/word/signed word/dword/signed dword) 1 << (byte) position_sprite::spriteno#0 @@ -761,12 +762,13 @@ position_sprite: { lda _2 ldy _1 sta SPRITES_XPOS,y - //SEG33 [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 -- vwuz1_gt_vbuc1_then_la1 + //SEG33 [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 -- vwuz1_ge_vwuc1_then_la1 lda x+1 + cmp #>$ff+1 + bcc !+ bne b1 lda x - cmp #$ff - beq !+ + cmp #<$ff+1 bcs b1 !: jmp b2 @@ -826,7 +828,7 @@ Statement [14] *((const byte*) SPRITES_YPOS#0 + (byte~) position_sprite::$0) ← Statement [15] (byte~) position_sprite::$1 ← (byte) position_sprite::spriteno#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ) always clobbers reg byte a Statement [16] (byte~) position_sprite::$2 ← < (word) position_sprite::x#0 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 position_sprite::$2 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 position_sprite::$2 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp ZP_BYTE:9 [ position_sprite::$1 ] -Statement [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 [ position_sprite::spriteno#0 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 ] ) always clobbers reg byte a +Statement [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 [ position_sprite::spriteno#0 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 ] ) always clobbers reg byte a Statement [19] (byte/signed byte/word/signed word/dword/signed dword~) position_sprite::$4 ← (byte/signed byte/word/signed word/dword/signed dword) 1 << (byte) position_sprite::spriteno#0 [ position_sprite::$4 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::$4 ] ) always clobbers reg byte a Statement [20] (byte/word/dword~) position_sprite::$5 ← (byte/signed byte/word/signed word/dword/signed dword~) position_sprite::$4 ^ (byte/word/signed word/dword/signed dword) $ff [ position_sprite::$5 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::$5 ] ) always clobbers reg byte a Statement [21] *((const byte*) SPRITES_XMSB#0) ← *((const byte*) SPRITES_XMSB#0) & (byte/word/dword~) position_sprite::$5 [ ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 ] ) always clobbers reg byte a @@ -838,7 +840,7 @@ Statement [13] (byte~) position_sprite::$0 ← (byte) position_sprite::spriteno# Statement [14] *((const byte*) SPRITES_YPOS#0 + (byte~) position_sprite::$0) ← (const byte) position_sprite::y#0 [ position_sprite::spriteno#0 position_sprite::x#0 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 ] ) always clobbers reg byte a Statement [15] (byte~) position_sprite::$1 ← (byte) position_sprite::spriteno#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ) always clobbers reg byte a Statement [16] (byte~) position_sprite::$2 ← < (word) position_sprite::x#0 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 position_sprite::$2 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 position_sprite::$2 ] ) always clobbers reg byte a -Statement [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 [ position_sprite::spriteno#0 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 ] ) always clobbers reg byte a +Statement [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 [ position_sprite::spriteno#0 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 ] ) always clobbers reg byte a Statement [19] (byte/signed byte/word/signed word/dword/signed dword~) position_sprite::$4 ← (byte/signed byte/word/signed word/dword/signed dword) 1 << (byte) position_sprite::spriteno#0 [ position_sprite::$4 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::$4 ] ) always clobbers reg byte a Statement [20] (byte/word/dword~) position_sprite::$5 ← (byte/signed byte/word/signed word/dword/signed dword~) position_sprite::$4 ^ (byte/word/signed word/dword/signed dword) $ff [ position_sprite::$5 ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 position_sprite::$5 ] ) always clobbers reg byte a Statement [21] *((const byte*) SPRITES_XMSB#0) ← *((const byte*) SPRITES_XMSB#0) & (byte/word/dword~) position_sprite::$5 [ ] ( main:2::position_sprite:8 [ main::s#2 main::xpos#2 ] ) always clobbers reg byte a @@ -860,16 +862,16 @@ Uplift Scope [main] 23.1: zp ZP_BYTE:2 [ main::s#2 main::s#1 ] 15.58: zp ZP_WORD Uplift Scope [position_sprite] 4: zp ZP_BYTE:8 [ position_sprite::$0 ] 4: zp ZP_BYTE:10 [ position_sprite::$2 ] 4: zp ZP_BYTE:11 [ position_sprite::$4 ] 4: zp ZP_BYTE:12 [ position_sprite::$5 ] 4: zp ZP_BYTE:13 [ position_sprite::$6 ] 2.5: zp ZP_WORD:6 [ position_sprite::x#0 ] 2.38: zp ZP_BYTE:5 [ position_sprite::spriteno#0 ] 2: zp ZP_BYTE:9 [ position_sprite::$1 ] Uplift Scope [] -Uplifting [main] best 849 combination reg byte x [ main::s#2 main::s#1 ] zp ZP_WORD:3 [ main::xpos#2 main::xpos#1 ] -Uplifting [position_sprite] best 827 combination reg byte a [ position_sprite::$0 ] reg byte a [ position_sprite::$2 ] reg byte a [ position_sprite::$4 ] reg byte a [ position_sprite::$5 ] zp ZP_BYTE:13 [ position_sprite::$6 ] zp ZP_WORD:6 [ position_sprite::x#0 ] zp ZP_BYTE:5 [ position_sprite::spriteno#0 ] zp ZP_BYTE:9 [ position_sprite::$1 ] +Uplifting [main] best 851 combination reg byte x [ main::s#2 main::s#1 ] zp ZP_WORD:3 [ main::xpos#2 main::xpos#1 ] +Uplifting [position_sprite] best 829 combination reg byte a [ position_sprite::$0 ] reg byte a [ position_sprite::$2 ] reg byte a [ position_sprite::$4 ] reg byte a [ position_sprite::$5 ] zp ZP_BYTE:13 [ position_sprite::$6 ] zp ZP_WORD:6 [ position_sprite::x#0 ] zp ZP_BYTE:5 [ position_sprite::spriteno#0 ] zp ZP_BYTE:9 [ position_sprite::$1 ] Limited combination testing to 100 combinations of 9216 possible. -Uplifting [] best 827 combination +Uplifting [] best 829 combination Attempting to uplift remaining variables inzp ZP_BYTE:13 [ position_sprite::$6 ] -Uplifting [position_sprite] best 821 combination reg byte a [ position_sprite::$6 ] +Uplifting [position_sprite] best 823 combination reg byte a [ position_sprite::$6 ] Attempting to uplift remaining variables inzp ZP_BYTE:5 [ position_sprite::spriteno#0 ] -Uplifting [position_sprite] best 821 combination zp ZP_BYTE:5 [ position_sprite::spriteno#0 ] +Uplifting [position_sprite] best 823 combination zp ZP_BYTE:5 [ position_sprite::spriteno#0 ] Attempting to uplift remaining variables inzp ZP_BYTE:9 [ position_sprite::$1 ] -Uplifting [position_sprite] best 817 combination reg byte y [ position_sprite::$1 ] +Uplifting [position_sprite] best 819 combination reg byte y [ position_sprite::$1 ] Coalescing zero page register with common assignment [ zp ZP_WORD:3 [ main::xpos#2 main::xpos#1 ] ] with [ zp ZP_WORD:6 [ position_sprite::x#0 ] ] - score: 1 Allocated (was zp ZP_WORD:3) zp ZP_WORD:2 [ main::xpos#2 main::xpos#1 position_sprite::x#0 ] Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:4 [ position_sprite::spriteno#0 ] @@ -969,12 +971,13 @@ position_sprite: { lda x //SEG32 [17] *((const byte*) SPRITES_XPOS#0 + (byte~) position_sprite::$1) ← (byte~) position_sprite::$2 -- pbuc1_derefidx_vbuyy=vbuaa sta SPRITES_XPOS,y - //SEG33 [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 -- vwuz1_gt_vbuc1_then_la1 + //SEG33 [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 -- vwuz1_ge_vwuc1_then_la1 lda x+1 + cmp #>$ff+1 + bcc !+ bne b1 lda x - cmp #$ff - beq !+ + cmp #<$ff+1 bcs b1 !: jmp b2 @@ -1177,7 +1180,7 @@ reg byte a [ position_sprite::$6 ] FINAL ASSEMBLER -Score: 562 +Score: 564 //SEG0 File Comments // Tests rolling sprite MSB by variable amount @@ -1256,12 +1259,13 @@ position_sprite: { lda x //SEG32 [17] *((const byte*) SPRITES_XPOS#0 + (byte~) position_sprite::$1) ← (byte~) position_sprite::$2 -- pbuc1_derefidx_vbuyy=vbuaa sta SPRITES_XPOS,y - //SEG33 [18] if((word) position_sprite::x#0>(byte/word/signed word/dword/signed dword) $ff) goto position_sprite::@1 -- vwuz1_gt_vbuc1_then_la1 + //SEG33 [18] if((word) position_sprite::x#0>=(byte/word/signed word/dword/signed dword) $ff+(byte/signed byte/word/signed word/dword/signed dword) 1) goto position_sprite::@1 -- vwuz1_ge_vwuc1_then_la1 lda x+1 + cmp #>$ff+1 + bcc !+ bne b1 lda x - cmp #$ff - beq !+ + cmp #<$ff+1 bcs b1 !: //SEG34 position_sprite::@2 diff --git a/src/test/ref/test-comparisons.asm b/src/test/ref/test-comparisons.asm index 01a95f948..0490fd644 100644 --- a/src/test/ref/test-comparisons.asm +++ b/src/test/ref/test-comparisons.asm @@ -107,9 +107,9 @@ main: { lda #>op4 sta printu.op+1 jsr printu - lda #$37 - cmp a - bcs b27 + lda a + cmp #$37+1 + bcc b27 ldx #'+' jmp b7 b27: @@ -174,9 +174,9 @@ main: { lda #>op8 sta printu.op+1 jsr printu - lda #$37 - cmp a - bcc b31 + lda a + cmp #$37+1 + bcs b31 ldx #'+' jmp b11 b31: diff --git a/src/test/ref/test-comparisons.cfg b/src/test/ref/test-comparisons.cfg index 29c9cd13f..c4d437def 100644 --- a/src/test/ref/test-comparisons.cfg +++ b/src/test/ref/test-comparisons.cfg @@ -86,7 +86,7 @@ main::@6: scope:[main] from main::@26 main::@47 [44] call printu to:main::@48 main::@48: scope:[main] from main::@6 - [45] if((byte) main::a#10<=(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@7 + [45] if((byte) main::a#10<(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7 to:main::@27 main::@27: scope:[main] from main::@48 [46] phi() @@ -142,7 +142,7 @@ main::@10: scope:[main] from main::@30 main::@52 [74] call printu to:main::@53 main::@53: scope:[main] from main::@10 - [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 + [75] if((byte) main::a#10>=(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@11 to:main::@31 main::@31: scope:[main] from main::@53 [76] phi() diff --git a/src/test/ref/test-comparisons.log b/src/test/ref/test-comparisons.log index 77935d650..0b7e6bcff 100644 --- a/src/test/ref/test-comparisons.log +++ b/src/test/ref/test-comparisons.log @@ -2085,6 +2085,8 @@ Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks Resolved ranged next value main::i#1 ← ++ main::i#10 to ++ Resolved ranged comparison value if(main::i#1!=rangelast(0,4)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 5 +Rewriting conditional comparison if((byte) main::a#10<=(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@7 +Rewriting conditional comparison if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 Culled Empty Block (label) print_ln::@2 Culled Empty Block (label) @12 Culled Empty Block (label) print_byte::@2 @@ -2546,7 +2548,7 @@ main::@6: scope:[main] from main::@26 main::@47 [44] call printu to:main::@48 main::@48: scope:[main] from main::@6 - [45] if((byte) main::a#10<=(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@7 + [45] if((byte) main::a#10<(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7 to:main::@27 main::@27: scope:[main] from main::@48 [46] phi() @@ -2602,7 +2604,7 @@ main::@10: scope:[main] from main::@30 main::@52 [74] call printu to:main::@53 main::@53: scope:[main] from main::@10 - [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 + [75] if((byte) main::a#10>=(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@11 to:main::@31 main::@31: scope:[main] from main::@53 [76] phi() @@ -3446,10 +3448,10 @@ main: { jmp b48 //SEG119 main::@48 b48: - //SEG120 [45] if((byte) main::a#10<=(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@7 -- vbuz1_le_vbuc1_then_la1 - lda #$37 - cmp a - bcs b7_from_b48 + //SEG120 [45] if((byte) main::a#10<(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7 -- vbuz1_lt_vbuc1_then_la1 + lda a + cmp #$37+1 + bcc b7_from_b48 //SEG121 [46] phi from main::@48 to main::@27 [phi:main::@48->main::@27] b27_from_b48: jmp b27 @@ -3654,10 +3656,10 @@ main: { jmp b53 //SEG200 main::@53 b53: - //SEG201 [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 -- vbuz1_gt_vbuc1_then_la1 - lda #$37 - cmp a - bcc b11_from_b53 + //SEG201 [75] if((byte) main::a#10>=(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@11 -- vbuz1_ge_vbuc1_then_la1 + lda a + cmp #$37+1 + bcs b11_from_b53 //SEG202 [76] phi from main::@53 to main::@31 [phi:main::@53->main::@31] b31_from_b53: jmp b31 @@ -4543,7 +4545,6 @@ Removing always clobbered register reg byte a as potential for zp ZP_BYTE:30 [ p Statement [51] if((byte) main::a#10<=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@8 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [73] (byte*~) print_char_cursor#143 ← (byte*) print_line_cursor#1 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ) always clobbers reg byte a -Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [88] if((byte) main::a#10>(byte) main::a#10) goto main::@13 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [103] (byte*~) print_char_cursor#147 ← (byte*) print_line_cursor#1 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 print_char_cursor#147 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 print_char_cursor#147 ] ) always clobbers reg byte a @@ -4579,7 +4580,6 @@ Statement [43] (byte*~) print_char_cursor#159 ← (byte*) print_line_cursor#1 [ Statement [51] if((byte) main::a#10<=*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@8 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [73] (byte*~) print_char_cursor#143 ← (byte*) print_line_cursor#1 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ) always clobbers reg byte a -Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [88] if((byte) main::a#10>(byte) main::a#10) goto main::@13 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [103] (byte*~) print_char_cursor#147 ← (byte*) print_line_cursor#1 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 print_char_cursor#147 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#12 printu::b#12 printu::res#12 print_char_cursor#147 ] ) always clobbers reg byte a @@ -4613,7 +4613,6 @@ Statement [55] (byte) printu::b#6 ← *((const byte[5]) main::cs#0 + (byte) main Removing always clobbered register reg byte y as potential for zp ZP_BYTE:10 [ main::r#47 ] Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [73] (byte*~) print_char_cursor#143 ← (byte*) print_line_cursor#1 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ) always clobbers reg byte a -Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a reg byte y Statement [85] (byte) printu::b#10 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 main::r#51 printu::a#10 printu::b#10 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 main::r#51 printu::a#10 printu::b#10 print_char_cursor#55 ] ) always clobbers reg byte y Removing always clobbered register reg byte y as potential for zp ZP_BYTE:14 [ main::r#51 ] @@ -4650,7 +4649,6 @@ Statement [51] if((byte) main::a#10<=*((const byte[5]) main::cs#0 + (byte) main: Statement [55] (byte) printu::b#6 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 main::r#47 printu::a#6 printu::b#6 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 main::r#47 printu::a#6 printu::b#6 print_char_cursor#55 ] ) always clobbers reg byte y Statement [58] if((byte) main::a#10<=(byte) main::a#10) goto main::@9 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [73] (byte*~) print_char_cursor#143 ← (byte*) print_line_cursor#1 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 printu::a#8 printu::b#8 printu::res#8 print_char_cursor#143 ] ) always clobbers reg byte a -Statement [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a Statement [81] if((byte) main::a#10>*((const byte[5]) main::cs#0 + (byte) main::i#10)) goto main::@12 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a reg byte y Statement [85] (byte) printu::b#10 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 main::r#51 printu::a#10 printu::b#10 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 main::r#51 printu::a#10 printu::b#10 print_char_cursor#55 ] ) always clobbers reg byte y Statement [88] if((byte) main::a#10>(byte) main::a#10) goto main::@13 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ( main:2 [ main::a#10 main::i#10 print_line_cursor#1 main::b#0 print_char_cursor#55 ] ) always clobbers reg byte a @@ -5079,10 +5077,10 @@ main: { jmp b48 //SEG119 main::@48 b48: - //SEG120 [45] if((byte) main::a#10<=(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@7 -- vbuz1_le_vbuc1_then_la1 - lda #$37 - cmp a - bcs b7_from_b48 + //SEG120 [45] if((byte) main::a#10<(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7 -- vbuz1_lt_vbuc1_then_la1 + lda a + cmp #$37+1 + bcc b7_from_b48 //SEG121 [46] phi from main::@48 to main::@27 [phi:main::@48->main::@27] b27_from_b48: jmp b27 @@ -5263,10 +5261,10 @@ main: { jmp b53 //SEG200 main::@53 b53: - //SEG201 [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 -- vbuz1_gt_vbuc1_then_la1 - lda #$37 - cmp a - bcc b11_from_b53 + //SEG201 [75] if((byte) main::a#10>=(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@11 -- vbuz1_ge_vbuc1_then_la1 + lda a + cmp #$37+1 + bcs b11_from_b53 //SEG202 [76] phi from main::@53 to main::@31 [phi:main::@53->main::@31] b31_from_b53: jmp b31 @@ -6833,10 +6831,10 @@ main: { //SEG118 [167] phi (byte*) print_char_cursor#95 = (byte*~) print_char_cursor#159 [phi:main::@6->printu#4] -- register_copy jsr printu //SEG119 main::@48 - //SEG120 [45] if((byte) main::a#10<=(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@7 -- vbuz1_le_vbuc1_then_la1 - lda #$37 - cmp a - bcs b27 + //SEG120 [45] if((byte) main::a#10<(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@7 -- vbuz1_lt_vbuc1_then_la1 + lda a + cmp #$37+1 + bcc b27 //SEG121 [46] phi from main::@48 to main::@27 [phi:main::@48->main::@27] //SEG122 main::@27 //SEG123 [47] phi from main::@27 to main::@7 [phi:main::@27->main::@7] @@ -6981,10 +6979,10 @@ main: { //SEG199 [167] phi (byte*) print_char_cursor#95 = (byte*~) print_char_cursor#143 [phi:main::@10->printu#4] -- register_copy jsr printu //SEG200 main::@53 - //SEG201 [75] if((byte) main::a#10>(byte/signed byte/word/signed word/dword/signed dword) $37) goto main::@11 -- vbuz1_gt_vbuc1_then_la1 - lda #$37 - cmp a - bcc b31 + //SEG201 [75] if((byte) main::a#10>=(byte/signed byte/word/signed word/dword/signed dword) $37+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@11 -- vbuz1_ge_vbuc1_then_la1 + lda a + cmp #$37+1 + bcs b31 //SEG202 [76] phi from main::@53 to main::@31 [phi:main::@53->main::@31] //SEG203 main::@31 //SEG204 [77] phi from main::@31 to main::@11 [phi:main::@31->main::@11] diff --git a/src/test/ref/test-interrupt-volatile-write.asm b/src/test/ref/test-interrupt-volatile-write.asm index c8569ce19..db8a6bd7f 100644 --- a/src/test/ref/test-interrupt-volatile-write.asm +++ b/src/test/ref/test-interrupt-volatile-write.asm @@ -17,9 +17,9 @@ main: { lda #>irq sta KERNEL_IRQ+1 b2: - lda #$a - cmp col - bcs b2 + lda col + cmp #$a+1 + bcc b2 lda #0 sta col jmp b2 diff --git a/src/test/ref/test-interrupt-volatile-write.cfg b/src/test/ref/test-interrupt-volatile-write.cfg index 10f49ecbe..c3b4336a6 100644 --- a/src/test/ref/test-interrupt-volatile-write.cfg +++ b/src/test/ref/test-interrupt-volatile-write.cfg @@ -14,7 +14,7 @@ main::@1: scope:[main] from main main::@2 main::@3 [5] (byte) col#14 ← phi( main/(byte) col#0 main::@3/(byte) col#1 ) to:main::@2 main::@2: scope:[main] from main::@1 - [6] if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 + [6] if((byte) col#14<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 diff --git a/src/test/ref/test-interrupt-volatile-write.log b/src/test/ref/test-interrupt-volatile-write.log index d6db707f6..800b80f40 100644 --- a/src/test/ref/test-interrupt-volatile-write.log +++ b/src/test/ref/test-interrupt-volatile-write.log @@ -131,6 +131,7 @@ Successful SSA optimization Pass2ConstantIfs Successful SSA optimization PassNEliminateUnusedVars Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks +Rewriting conditional comparison if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@4 Culled Empty Block (label) main::@4 Culled Empty Block (label) @3 Successful SSA optimization Pass2CullEmptyBlocks @@ -168,7 +169,7 @@ main::@1: scope:[main] from main main::@2 main::@3 [5] (byte) col#14 ← phi( main/(byte) col#0 main::@3/(byte) col#1 ) to:main::@2 main::@2: scope:[main] from main::@1 - [6] if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 + [6] if((byte) col#14<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 @@ -258,10 +259,10 @@ main: { jmp b2 //SEG16 main::@2 b2: - //SEG17 [6] if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 -- vbuz1_le_vbuc1_then_la1 - lda #$a - cmp col - bcs b1_from_b2 + //SEG17 [6] if((byte) col#14<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 -- vbuz1_lt_vbuc1_then_la1 + lda col + cmp #$a+1 + bcc b1_from_b2 jmp b3 //SEG18 main::@3 b3: @@ -305,7 +306,7 @@ irq: { REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] (byte) col#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ col#0 ] ( ) always clobbers reg byte a Statement [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ col#0 ] ( main:2 [ col#0 ] ) always clobbers reg byte a -Statement [6] if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [6] if((byte) col#14<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ col#1 ] ( main:2 [ col#1 ] ) always clobbers reg byte a Statement asm { lda$dc0d } always clobbers reg byte a Statement [9] *((const byte*) BGCOL#0) ← (byte) col#0 [ col#0 ] ( [ col#0 ] ) always clobbers reg byte a @@ -373,10 +374,10 @@ main: { jmp b2 //SEG16 main::@2 b2: - //SEG17 [6] if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 -- vbuz1_le_vbuc1_then_la1 - lda #$a - cmp col - bcs b1_from_b2 + //SEG17 [6] if((byte) col#14<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 -- vbuz1_lt_vbuc1_then_la1 + lda col + cmp #$a+1 + bcc b1_from_b2 jmp b3 //SEG18 main::@3 b3: @@ -520,10 +521,10 @@ main: { //SEG15 main::@1 //SEG16 main::@2 b2: - //SEG17 [6] if((byte) col#14<=(byte/signed byte/word/signed word/dword/signed dword) $a) goto main::@1 -- vbuz1_le_vbuc1_then_la1 - lda #$a - cmp col - bcs b2 + //SEG17 [6] if((byte) col#14<(byte/signed byte/word/signed word/dword/signed dword) $a+(byte/signed byte/word/signed word/dword/signed dword) 1) goto main::@1 -- vbuz1_lt_vbuc1_then_la1 + lda col + cmp #$a+1 + bcc b2 //SEG18 main::@3 //SEG19 [7] (byte) col#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 lda #0