From 82dd27e6279a1e486aedbc766a9558bf902818ef Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sun, 1 Aug 2021 17:24:12 +0200 Subject: [PATCH] Parameters and return values now work for calling convention stack. Pointers to functions with parameters/return values now work. Parameter transfer through stack of structs/unions now work. #121 --- .idea/codeStyles/Project.xml | 15 +- .../cache/fragment-cache-csg65ce02.asm | 2 +- .../cache/fragment-cache-mega45gs02.asm | 127 +- .../fragment/cache/fragment-cache-mos6502.asm | 2 +- .../cache/fragment-cache-mos6502x.asm | 525 ++++--- .../cache/fragment-cache-rom6502x.asm | 2 +- .../cache/fragment-cache-wdc65c02.asm | 2 +- .../_stackidxstruct_1_vbuc1=vssm1.asm | 3 + .../_stackidxstruct_2_vbuc1=vssm1.asm | 5 + .../_stackidxstruct_3_vbuc1=vssm1.asm | 7 + .../_stackidxstruct_4_vbuc1=vssm1.asm | 9 + .../_stackidxstruct_vbuc1_vbuc2=vssm1.asm | 9 + .../_stackidxword_vbuc1=vwum1.asm | 2 +- .../_stackpushstruct_1_=vssm1.asm | 2 + .../_stackpushstruct_2_=vssm1.asm | 4 + .../_stackpushstruct_3_=vssm1.asm | 6 + .../_stackpushstruct_4_=vssm1.asm | 8 + .../_stackpushstruct_vbuyy_=vssm1.asm | 5 + .../mos6502-common/_stackpushsword_=vwsm1.asm | 2 +- .../vssm1=_stackidxstruct_1_vbuc1.asm | 3 + .../vssm1=_stackidxstruct_2_vbuc1.asm | 5 + .../vssm1=_stackidxstruct_3_vbuc1.asm | 7 + .../vssm1=_stackidxstruct_4_vbuc1.asm | 9 + .../vssm1=_stackidxstruct_vbuc1_vbuc2.asm | 9 + .../vssm1=_stackpullstruct_1_.asm | 2 + .../vssm1=_stackpullstruct_2_.asm | 4 + .../vssm1=_stackpullstruct_3_.asm | 6 + .../vssm1=_stackpullstruct_4_.asm | 8 + .../vssm1=_stackpullstruct_vbuc1_.asm | 7 + .../vwum1=_stackidxword_vbuc1.asm | 2 +- .../AsmFragmentInstanceSpecBuilder.java | 29 +- .../dk/camelot64/kickc/model/CallGraph.java | 22 +- .../kickc/model/CallingConventionStack.java | 40 +- .../kickc/model/iterator/ProgramValue.java | 21 +- .../model/iterator/ProgramValueIterator.java | 2 + .../statements/StatementCallExecute.java | 41 +- .../statements/StatementCallFinalize.java | 25 +- .../statements/StatementCallPrepare.java | 23 +- .../kickc/model/symbols/Procedure.java | 2 +- .../kickc/passes/Pass1AddressOfHandling.java | 6 +- .../kickc/passes/Pass1CallStack.java | 30 +- .../passes/Pass1CallStackVarConvert.java | 28 +- .../kickc/passes/Pass1UnwindStructValues.java | 3 + .../kickc/passes/Pass2AssertBlocks.java | 6 +- ...ass2ConstantCallPointerIdentification.java | 26 +- .../passes/Pass2ConstantIdentification.java | 8 +- .../passes/Pass2EliminateUnusedBlocks.java | 5 +- .../kickc/passes/Pass4CodeGeneration.java | 104 +- .../passes/Pass4InterruptClobberFix.java | 10 +- .../calcs/PassNCalcBlockSuccessorClosure.java | 3 +- .../calcs/PassNCalcLiveRangeVariables.java | 34 +- .../unwinding/ValueSourceParamValue.java | 4 + .../kickc/test/TestProgramsFast.java | 15 +- src/test/kc/function-pointer-return-1.c | 31 + .../kc/procedure-callingconvention-stack-10.c | 1 + .../kc/procedure-callingconvention-stack-11.c | 1 + src/test/ref/examples/c64/music/music.cfg | 11 +- src/test/ref/examples/c64/music/music.log | 46 +- src/test/ref/examples/c64/music/music_irq.cfg | 4 +- src/test/ref/examples/c64/music/music_irq.log | 24 +- src/test/ref/examples/mega65/banked-music.cfg | 123 +- src/test/ref/examples/mega65/banked-music.log | 597 +++---- src/test/ref/examples/mega65/raster65.cfg | 273 ++-- src/test/ref/examples/mega65/raster65.log | 1382 +++++++++-------- src/test/ref/examples/mega65/raster65.sym | 4 +- src/test/ref/examples/rom/rom.asm | 4 +- src/test/ref/examples/rom/rom.cfg | 2 +- src/test/ref/examples/rom/rom.log | 26 +- src/test/ref/examples/rom/rom.sym | 2 +- .../ref/function-pointer-noarg-call-10.cfg | 2 +- .../ref/function-pointer-noarg-call-10.log | 24 +- .../ref/function-pointer-noarg-call-10.sym | 2 +- .../ref/function-pointer-noarg-call-11.cfg | 4 +- .../ref/function-pointer-noarg-call-11.log | 22 +- .../ref/function-pointer-noarg-call-12.cfg | 4 +- .../ref/function-pointer-noarg-call-12.log | 37 +- .../ref/function-pointer-noarg-call-12.sym | 4 +- .../ref/function-pointer-noarg-call-14.cfg | 2 +- .../ref/function-pointer-noarg-call-14.log | 14 +- .../ref/function-pointer-noarg-call-2.cfg | 2 +- .../ref/function-pointer-noarg-call-2.log | 22 +- .../ref/function-pointer-noarg-call-2.sym | 2 +- .../ref/function-pointer-noarg-call-3.cfg | 2 +- .../ref/function-pointer-noarg-call-3.log | 35 +- .../ref/function-pointer-noarg-call-3.sym | 4 +- .../ref/function-pointer-noarg-call-4.cfg | 2 +- .../ref/function-pointer-noarg-call-4.log | 11 +- .../ref/function-pointer-noarg-call-5.cfg | 2 +- .../ref/function-pointer-noarg-call-5.log | 36 +- .../ref/function-pointer-noarg-call-5.sym | 4 +- .../ref/function-pointer-noarg-call-6.cfg | 2 +- .../ref/function-pointer-noarg-call-6.log | 11 +- .../ref/function-pointer-noarg-call-7.cfg | 2 +- .../ref/function-pointer-noarg-call-7.log | 11 +- .../ref/function-pointer-noarg-call-8.cfg | 2 +- .../ref/function-pointer-noarg-call-8.log | 11 +- .../ref/function-pointer-noarg-call-9.cfg | 4 +- .../ref/function-pointer-noarg-call-9.log | 22 +- src/test/ref/function-pointer-noarg-call.cfg | 2 +- src/test/ref/function-pointer-noarg-call.log | 11 +- src/test/ref/function-pointer-param-0.asm | 105 ++ src/test/ref/function-pointer-param-0.cfg | 64 + src/test/ref/function-pointer-param-0.log | 758 +++++++++ src/test/ref/function-pointer-param-0.sym | 30 + .../ref/function-pointer-param-workaround.cfg | 2 +- .../ref/function-pointer-param-workaround.log | 42 +- .../ref/function-pointer-param-workaround.sym | 6 +- src/test/ref/function-pointer-return-1.asm | 71 + src/test/ref/function-pointer-return-1.cfg | 41 + src/test/ref/function-pointer-return-1.log | 561 +++++++ src/test/ref/function-pointer-return-1.sym | 28 + src/test/ref/function-pointer-return.asm | 11 + src/test/ref/function-pointer-return.cfg | 30 +- src/test/ref/function-pointer-return.log | 198 ++- src/test/ref/function-pointer-return.sym | 11 +- .../procedure-callingconvention-stack-0.asm | 4 +- .../procedure-callingconvention-stack-0.cfg | 2 +- .../procedure-callingconvention-stack-0.log | 26 +- .../procedure-callingconvention-stack-0.sym | 2 +- .../procedure-callingconvention-stack-1.asm | 4 +- .../procedure-callingconvention-stack-1.cfg | 2 +- .../procedure-callingconvention-stack-1.log | 26 +- .../procedure-callingconvention-stack-1.sym | 2 +- .../procedure-callingconvention-stack-10.asm | 54 +- .../procedure-callingconvention-stack-10.cfg | 49 +- .../procedure-callingconvention-stack-10.log | 568 ++++--- .../procedure-callingconvention-stack-10.sym | 44 +- .../procedure-callingconvention-stack-11.asm | 123 +- .../procedure-callingconvention-stack-11.cfg | 75 +- .../procedure-callingconvention-stack-11.log | 1002 +++++------- .../procedure-callingconvention-stack-11.sym | 74 +- .../procedure-callingconvention-stack-13.asm | 4 +- .../procedure-callingconvention-stack-13.cfg | 2 +- .../procedure-callingconvention-stack-13.log | 24 +- .../procedure-callingconvention-stack-13.sym | 2 +- .../procedure-callingconvention-stack-2.asm | 6 +- .../procedure-callingconvention-stack-2.cfg | 2 +- .../procedure-callingconvention-stack-2.log | 28 +- .../procedure-callingconvention-stack-2.sym | 2 +- .../procedure-callingconvention-stack-3.asm | 6 +- .../procedure-callingconvention-stack-3.cfg | 2 +- .../procedure-callingconvention-stack-3.log | 28 +- .../procedure-callingconvention-stack-3.sym | 2 +- .../procedure-callingconvention-stack-4.asm | 4 +- .../procedure-callingconvention-stack-4.cfg | 2 +- .../procedure-callingconvention-stack-4.log | 26 +- .../procedure-callingconvention-stack-4.sym | 2 +- .../procedure-callingconvention-stack-5.asm | 6 +- .../procedure-callingconvention-stack-5.cfg | 2 +- .../procedure-callingconvention-stack-5.log | 28 +- .../procedure-callingconvention-stack-5.sym | 2 +- src/test/ref/procedure-declare-8.cfg | 4 +- src/test/ref/procedure-declare-8.log | 22 +- src/test/ref/type-truncate.asm | 20 + src/test/ref/type-truncate.cfg | 8 + src/test/ref/type-truncate.log | 157 ++ src/test/ref/type-truncate.sym | 6 + 157 files changed, 5246 insertions(+), 3298 deletions(-) create mode 100644 src/main/fragment/mos6502-common/_stackidxstruct_1_vbuc1=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackidxstruct_2_vbuc1=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackidxstruct_3_vbuc1=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackidxstruct_4_vbuc1=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackidxstruct_vbuc1_vbuc2=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackpushstruct_1_=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackpushstruct_2_=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackpushstruct_3_=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackpushstruct_4_=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/_stackpushstruct_vbuyy_=vssm1.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackidxstruct_1_vbuc1.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackidxstruct_2_vbuc1.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackidxstruct_3_vbuc1.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackidxstruct_4_vbuc1.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackidxstruct_vbuc1_vbuc2.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackpullstruct_1_.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackpullstruct_2_.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackpullstruct_3_.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackpullstruct_4_.asm create mode 100644 src/main/fragment/mos6502-common/vssm1=_stackpullstruct_vbuc1_.asm create mode 100644 src/test/kc/function-pointer-return-1.c create mode 100644 src/test/ref/function-pointer-param-0.asm create mode 100644 src/test/ref/function-pointer-param-0.cfg create mode 100644 src/test/ref/function-pointer-param-0.log create mode 100644 src/test/ref/function-pointer-param-0.sym create mode 100644 src/test/ref/function-pointer-return-1.asm create mode 100644 src/test/ref/function-pointer-return-1.cfg create mode 100644 src/test/ref/function-pointer-return-1.log create mode 100644 src/test/ref/function-pointer-return-1.sym create mode 100644 src/test/ref/type-truncate.asm create mode 100644 src/test/ref/type-truncate.cfg create mode 100644 src/test/ref/type-truncate.log create mode 100644 src/test/ref/type-truncate.sym diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index b849a12e3..02b577df4 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -7,18 +7,9 @@ - diff --git a/src/main/fragment/cache/fragment-cache-csg65ce02.asm b/src/main/fragment/cache/fragment-cache-csg65ce02.asm index e135f0971..e4821d794 100644 --- a/src/main/fragment/cache/fragment-cache-csg65ce02.asm +++ b/src/main/fragment/cache/fragment-cache-csg65ce02.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 9a29ecc94 9a29eec1a +//KICKC FRAGMENT CACHE 8c8c73a6a 8c8c75a58 //FRAGMENT vbuzz=vbuc1 ldz #{c1} //FRAGMENT vbuzz_lt_vbuc1_then_la1 diff --git a/src/main/fragment/cache/fragment-cache-mega45gs02.asm b/src/main/fragment/cache/fragment-cache-mega45gs02.asm index 1d54a5bbf..0debde85f 100644 --- a/src/main/fragment/cache/fragment-cache-mega45gs02.asm +++ b/src/main/fragment/cache/fragment-cache-mega45gs02.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 9a29ecc94 9a29eec1a +//KICKC FRAGMENT CACHE 8c8c73a6a 8c8c75a58 //FRAGMENT _deref_pbuc1=vbuc2 lda #{c2} sta {c1} @@ -1647,10 +1647,6 @@ tax inc {c1},x //FRAGMENT pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx inc {c1},x -//FRAGMENT vbuaa=_byte0_vwuz1 -lda {z1} -//FRAGMENT vbuxx=_byte0_vwuz1 -ldx {z1} //FRAGMENT vbuaa=_byte1_vwuz1 lda {z1}+1 //FRAGMENT vbuxx=_byte1_vwuz1 @@ -1690,11 +1686,6 @@ ora {z2} sta {z1} //FRAGMENT vbuz1=vbuxx_bor_vbuxx stx {z1} -//FRAGMENT vbuyy=_byte0_vwuz1 -ldy {z1} -//FRAGMENT vbuzz=_byte0_vwuz1 -lda {z1} -taz //FRAGMENT vbuyy=_byte1_vwuz1 ldy {z1}+1 //FRAGMENT vbuzz=_byte1_vwuz1 @@ -1704,6 +1695,10 @@ taz tya ora {z2} sta {z1} +//FRAGMENT vbuz1=vbuz2_bor_vbuzz +tza +ora {z2} +sta {z1} //FRAGMENT pbuc1_derefidx_vbuyy=_inc_pbuc1_derefidx_vbuyy lda {c1},y inc @@ -1722,32 +1717,6 @@ beq {la1} //FRAGMENT _deref_pbuc1_eq_vbuzz_then_la1 cpz {c1} beq {la1} -//FRAGMENT vbuaa=vbuz1_bor_vbuaa -ora {z1} -//FRAGMENT vbuxx=vbuz1_bor_vbuaa -ora {z1} -tax -//FRAGMENT vbuyy=vbuz1_bor_vbuaa -ora {z1} -tay -//FRAGMENT vbuzz=vbuz1_bor_vbuaa -ora {z1} -taz -//FRAGMENT vbuz1=vbuz2_bor_vbuzz -tza -ora {z2} -sta {z1} -//FRAGMENT vbuaa=vbuxx_bor_vbuaa -stx $ff -ora $ff -//FRAGMENT vbuaa=vbuyy_bor_vbuaa -sty $ff -ora $ff -//FRAGMENT vbuaa=vbuzz_bor_vbuaa -tay -tza -sty $ff -ora $ff //FRAGMENT vduz1=vduc1 lda #<{c1} sta {z1} @@ -2388,92 +2357,15 @@ dey bne !- !e: taz -//FRAGMENT vbuaa=_byte1__word_vduz1 -lda {z1}+1 -//FRAGMENT vbuxx=_byte1__word_vduz1 -lda {z1}+1 -tax -//FRAGMENT vbuyy=_byte1__word_vduz1 -lda {z1}+1 -tay -//FRAGMENT vbuzz=_byte1__word_vduz1 -lda {z1}+1 -taz -//FRAGMENT vbuaa=_byte0_vduz1 -lda {z1} -//FRAGMENT vbuxx=_byte0_vduz1 -ldx {z1} //FRAGMENT vbuaa=_byte1_vduz1 lda {z1}+1 //FRAGMENT vbuxx=_byte1_vduz1 ldx {z1}+1 -//FRAGMENT vbuaa=vbuz1_bor_vbuz2 -lda {z1} -ora {z2} -//FRAGMENT vbuaa=vbuz1_bor_vbuxx -txa -ora {z1} -//FRAGMENT vbuaa=vbuz1_bor_vbuyy -tya -ora {z1} -//FRAGMENT vbuaa=vbuz1_bor_vbuzz -tza -ora {z1} -//FRAGMENT vbuxx=vbuz1_bor_vbuz2 -lda {z1} -ora {z2} -tax -//FRAGMENT vbuxx=vbuz1_bor_vbuxx -txa -ora {z1} -tax -//FRAGMENT vbuxx=vbuz1_bor_vbuyy -tya -ora {z1} -tax -//FRAGMENT vbuxx=vbuz1_bor_vbuzz -tza -ora {z1} -tax -//FRAGMENT vbuyy=vbuz1_bor_vbuz2 -lda {z1} -ora {z2} -tay -//FRAGMENT vbuyy=vbuz1_bor_vbuxx -txa -ora {z1} -tay -//FRAGMENT vbuyy=vbuz1_bor_vbuyy -tya -ora {z1} -tay -//FRAGMENT vbuyy=vbuz1_bor_vbuzz -tza -ora {z1} -tay -//FRAGMENT vbuzz=vbuz1_bor_vbuz2 -lda {z1} -ora {z2} -taz -//FRAGMENT vbuzz=vbuz1_bor_vbuxx -txa -ora {z1} -taz -//FRAGMENT vbuzz=vbuz1_bor_vbuyy -tya -ora {z1} -taz -//FRAGMENT vbuzz=vbuz1_bor_vbuzz -tza -ora {z1} -taz -//FRAGMENT vbuyy=_byte0_vduz1 -ldy {z1} -//FRAGMENT vbuzz=_byte0_vduz1 -lda {z1} -taz //FRAGMENT vbuyy=_byte1_vduz1 ldy {z1}+1 +//FRAGMENT vbuzz=_byte1_vduz1 +lda {z1}+1 +taz //FRAGMENT pbuc1_derefidx_vbuyy=vbuaa sta {c1},y //FRAGMENT pbuc1_derefidx_vbuzz=vbuaa @@ -2563,6 +2455,3 @@ sta {z1}+3 NO_SYNTHESIS //FRAGMENT vduz1=vwsc1 NO_SYNTHESIS -//FRAGMENT vbuzz=_byte1_vduz1 -lda {z1}+1 -taz diff --git a/src/main/fragment/cache/fragment-cache-mos6502.asm b/src/main/fragment/cache/fragment-cache-mos6502.asm index d4131120a..c6415db7f 100644 --- a/src/main/fragment/cache/fragment-cache-mos6502.asm +++ b/src/main/fragment/cache/fragment-cache-mos6502.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 9a29ecc94 9a29eec1a +//KICKC FRAGMENT CACHE 8c8c73a6a 8c8c75a58 //FRAGMENT vbuz1=vbuc1 lda #{c1} sta {z1} diff --git a/src/main/fragment/cache/fragment-cache-mos6502x.asm b/src/main/fragment/cache/fragment-cache-mos6502x.asm index 0c6346bea..ba12de26c 100644 --- a/src/main/fragment/cache/fragment-cache-mos6502x.asm +++ b/src/main/fragment/cache/fragment-cache-mos6502x.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 9a29ecc94 9a29eec1a +//KICKC FRAGMENT CACHE 8c8c73a6a 8c8c75a58 //FRAGMENT vbuz1=vbuc1 lda #{c1} sta {z1} @@ -636,17 +636,136 @@ inc {c1} //FRAGMENT isr_rom_min_c64_exit jmp $ea81 +//FRAGMENT _deref_pwuc1=vbuc2 +lda #<{c2} +sta {c1} +lda #>{c2} +sta {c1}+1 +//FRAGMENT vwuz1=vwuc1 +lda #<{c1} +sta {z1} +lda #>{c1} +sta {z1}+1 +//FRAGMENT _deref_pwuc1=_deref_pwuc2 +lda {c2} +sta {c1} +lda {c2}+1 +sta {c1}+1 //FRAGMENT vbuz1=_deref_pbuc1 lda {c1} sta {z1} -//FRAGMENT vbuz1=vbuz2_plus_vbuc1 -lax {z2} -axs #-[{c1}] -stx {z1} +//FRAGMENT vbuz1=_byte1_vwuz2 +lda {z2}+1 +sta {z1} +//FRAGMENT vwuz1=_word_vbuz2 +lda {z2} +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz2_plus_vbuz3 +lda {z3} +clc +adc {z2} +sta {z1} +lda #0 +adc {z2}+1 +sta {z1}+1 +//FRAGMENT vbuz1=_byte0_vwuz2 +lda {z2} +sta {z1} +//FRAGMENT vwuz1=vwuz2_ror_8 +lda {z2}+1 +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT 0_eq_vbuz1_then_la1 +lda {z1} +beq {la1} +//FRAGMENT _deref_pbuc1_neq_0_then_la1 +lda {c1} +bne {la1} //FRAGMENT vbuaa=_deref_pbuc1 lda {c1} //FRAGMENT vbuxx=_deref_pbuc1 ldx {c1} +//FRAGMENT vbuaa=_byte1_vwuz1 +lda {z1}+1 +//FRAGMENT vbuxx=_byte1_vwuz1 +ldx {z1}+1 +//FRAGMENT vwuz1=_word_vbuaa +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=_word_vbuxx +txa +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=_word_vbuyy +tya +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz2_plus_vbuxx +txa +clc +adc {z2} +sta {z1} +lda #0 +adc {z2}+1 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz2_plus_vbuyy +tya +clc +adc {z2} +sta {z1} +lda #0 +adc {z2}+1 +sta {z1}+1 +//FRAGMENT vbuaa=_byte0_vwuz1 +lda {z1} +//FRAGMENT vbuxx=_byte0_vwuz1 +ldx {z1} +//FRAGMENT 0_eq_vbuaa_then_la1 +cmp #0 +beq {la1} +//FRAGMENT vbuyy=_byte1_vwuz1 +ldy {z1}+1 +//FRAGMENT vbuyy=_byte0_vwuz1 +ldy {z1} +//FRAGMENT 0_eq_vbuxx_then_la1 +cpx #0 +beq {la1} +//FRAGMENT 0_eq_vbuyy_then_la1 +cpy #0 +beq {la1} +//FRAGMENT vbuyy=_deref_pbuc1 +ldy {c1} +//FRAGMENT vwuz1=vwuz1_plus_vbuxx +txa +clc +adc {z1} +sta {z1} +bcc !+ +inc {z1}+1 +!: +//FRAGMENT vwuz1=vwuz1_ror_8 +lda {z1}+1 +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz1_plus_vbuyy +tya +clc +adc {z1} +sta {z1} +bcc !+ +inc {z1}+1 +!: +//FRAGMENT vbuz1=vbuz2_plus_vbuc1 +lax {z2} +axs #-[{c1}] +stx {z1} //FRAGMENT vbuaa=vbuz1_plus_vbuc1 lda #{c1} clc @@ -705,8 +824,6 @@ txa clc adc #{c1} tay -//FRAGMENT vbuyy=_deref_pbuc1 -ldy {c1} //FRAGMENT vbuz1=vbuyy_plus_vbuc1 tya clc @@ -835,12 +952,6 @@ bne {la1} lda #{c1} ldy #0 sta ({z1}),y -//FRAGMENT vbuz1=_byte1_vwuz2 -lda {z2}+1 -sta {z1} -//FRAGMENT vbuz1=_byte0_vwuz2 -lda {z2} -sta {z1} //FRAGMENT vbuz1=vbuz2_ror_4 lda {z2} lsr @@ -863,14 +974,6 @@ sta ({z1}),y tya ldy #0 sta ({z1}),y -//FRAGMENT vbuaa=_byte1_vwuz1 -lda {z1}+1 -//FRAGMENT vbuxx=_byte1_vwuz1 -ldx {z1}+1 -//FRAGMENT vbuaa=_byte0_vwuz1 -lda {z1} -//FRAGMENT vbuxx=_byte0_vwuz1 -ldx {z1} //FRAGMENT vbuaa=vbuz1_ror_4 lda {z1} lsr @@ -1061,9 +1164,6 @@ tax tya eor #$ff tay -//FRAGMENT _deref_pbuc1_neq_0_then_la1 -lda {c1} -bne {la1} //FRAGMENT pbum1=pbuc1 lda #<{c1} sta {m1} @@ -1831,16 +1931,6 @@ sta ({z1}),y lda {c1},y ldy #0 sta ({z1}),y -//FRAGMENT vwuz1=vwuc1 -lda #<{c1} -sta {z1} -lda #>{c1} -sta {z1}+1 -//FRAGMENT vwuz1=_word_vbuz2 -lda {z2} -sta {z1} -lda #0 -sta {z1}+1 //FRAGMENT vwuz1=vbuc1 lda #<{c1} sta {z1} @@ -1851,20 +1941,6 @@ lda {c1} sta {z1}+1 lda {c2} sta {z1} -//FRAGMENT vwuz1=_word_vbuaa -sta {z1} -lda #0 -sta {z1}+1 -//FRAGMENT vwuz1=_word_vbuxx -txa -sta {z1} -lda #0 -sta {z1}+1 -//FRAGMENT vwuz1=_word_vbuyy -tya -sta {z1} -lda #0 -sta {z1}+1 //FRAGMENT vbuz1=vbuyy_ror_4 tya lsr @@ -1895,10 +1971,6 @@ tay //FRAGMENT vbuz1=pbuc1_derefidx_vbuyy lda {c1},y sta {z1} -//FRAGMENT vbuyy=_byte0_vwuz1 -ldy {z1} -//FRAGMENT vbuyy=_byte1_vwuz1 -ldy {z1}+1 //FRAGMENT vbsz1=vbsc1 lda #{c1} sta {z1} @@ -2313,6 +2385,42 @@ tay sta {c1},x //FRAGMENT vbsyy=vbsc1 ldy #{c1} +//FRAGMENT vbuz1=_stackidxbyte_vbuc1 +tsx +lda STACK_BASE+{c1},x +sta {z1} +//FRAGMENT _stackpushbyte_=vbuz1 +lda {z1} +pha +//FRAGMENT _stackpullbyte_1 +pla +//FRAGMENT vbuz1_eq_vbuc1_then_la1 +lda #{c1} +cmp {z1} +beq {la1} +//FRAGMENT vbuaa=_stackidxbyte_vbuc1 +tsx +lda STACK_BASE+{c1},x +//FRAGMENT vbuxx=_stackidxbyte_vbuc1 +tsx +lda STACK_BASE+{c1},x +tax +//FRAGMENT vbuyy=_stackidxbyte_vbuc1 +tsx +lda STACK_BASE+{c1},x +tay +//FRAGMENT _stackpushbyte_=vbuyy +tya +pha +//FRAGMENT vbuaa_eq_vbuc1_then_la1 +cmp #{c1} +beq {la1} +//FRAGMENT vbuxx_eq_vbuc1_then_la1 +cpx #{c1} +beq {la1} +//FRAGMENT vbuyy_eq_vbuc1_then_la1 +cpy #{c1} +beq {la1} //FRAGMENT vbuxx=vbuxx_plus_vbuc1 txa axs #-[{c1}] @@ -2788,11 +2896,6 @@ sta {c1},x //FRAGMENT pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuyy lda {c2},y sta {c1},y -//FRAGMENT _deref_pwuc1=_deref_pwuc2 -lda {c2} -sta {c1} -lda {c2}+1 -sta {c1}+1 //FRAGMENT pbuc1_derefidx_vbuaa=pbuc2_derefidx_vbuz1 ldx {z1} tay @@ -3185,9 +3288,6 @@ tay txa tay sta ({z1}),y -//FRAGMENT _deref_pbuc1=_byte_pprz1 -lda {z1} -sta {c1} //FRAGMENT vwuz1=_deref_pwuc1_minus_vwuc2 sec lda {c1} @@ -3321,9 +3421,6 @@ sta {z1} lda #0 sbc {z1}+1 sta {z1}+1 -//FRAGMENT 0_eq_vbuz1_then_la1 -lda {z1} -beq {la1} //FRAGMENT vwsz1=vwsz1_ror_1 lda {z1}+1 cmp #$80 @@ -3346,10 +3443,6 @@ sta {z1} lda {z1}+1 sbc {c1}+1,y sta {z1}+1 -//FRAGMENT vbuz1_eq_vbuc1_then_la1 -lda #{c1} -cmp {z1} -beq {la1} //FRAGMENT vwuz1=vwuz1_plus_pwuc1_derefidx_vbuz2 ldy {z2} clc @@ -3587,9 +3680,6 @@ sta ({z1}),y tay lda #{c1} sta ({z1}),y -//FRAGMENT 0_eq_vbuxx_then_la1 -cpx #0 -beq {la1} //FRAGMENT vwuz1=vwuz1_minus_pwuc1_derefidx_vbuaa tay lda {z1} @@ -3615,9 +3705,6 @@ sta {z1} lda {z1}+1 sbc {c1}+1,y sta {z1}+1 -//FRAGMENT vbuxx_eq_vbuc1_then_la1 -cpx #{c1} -beq {la1} //FRAGMENT vwuz1=vwuz1_plus_pwuc1_derefidx_vbuaa tay clc @@ -3646,15 +3733,9 @@ sta {z1}+1 //FRAGMENT vbuxx=vbuxx_minus_2 dex dex -//FRAGMENT 0_eq_vbuyy_then_la1 -cpy #0 -beq {la1} //FRAGMENT vbuyy=vbuyy_minus_2 dey dey -//FRAGMENT vbuyy_eq_vbuc1_then_la1 -cpy #{c1} -beq {la1} //FRAGMENT vbuz1=vbuz2_bor_vbuyy tya ora {z2} @@ -3714,15 +3795,15 @@ sta {z1} bcc !+ inc {z1}+1 !: -//FRAGMENT vbuaa_eq_vbuc1_then_la1 -cmp #{c1} -beq {la1} -//FRAGMENT vbuz1_eq_vbuxx_then_la1 -cpx {z1} +//FRAGMENT vbuaa_eq_vbuz1_then_la1 +cmp {z1} beq {la1} //FRAGMENT vbuxx_eq_vbuz1_then_la1 cpx {z1} beq {la1} +//FRAGMENT vbuz1_eq_vbuxx_then_la1 +cpx {z1} +beq {la1} //FRAGMENT vbuxx_eq_vbuaa_then_la1 tay sty $ff @@ -4250,6 +4331,15 @@ txa sty $ff ora $ff tay +//FRAGMENT _deref_pduc1=vduc2 +lda #<{c2} +sta {c1} +lda #>{c2} +sta {c1}+1 +lda #<{c2}>>$10 +sta {c1}+2 +lda #>{c2}>>$10 +sta {c1}+3 //FRAGMENT vbuz1=_dec_vbuz1 dec {z1} //FRAGMENT vbuxx=_dec_vbuxx @@ -4401,14 +4491,6 @@ bne {la1} lda {z1} cmp #<{c1} bne {la1} -//FRAGMENT vwuz1=vwuz2_plus_vbuz3 -lda {z3} -clc -adc {z2} -sta {z1} -lda #0 -adc {z2}+1 -sta {z1}+1 //FRAGMENT vbuz1=_byte_vwuz2 lda {z2} sta {z1} @@ -4476,22 +4558,6 @@ tay tya ora #{c1} tay -//FRAGMENT vwuz1=vwuz2_plus_vbuxx -txa -clc -adc {z2} -sta {z1} -lda #0 -adc {z2}+1 -sta {z1}+1 -//FRAGMENT vwuz1=vwuz2_plus_vbuyy -tya -clc -adc {z2} -sta {z1} -lda #0 -adc {z2}+1 -sta {z1}+1 //FRAGMENT vbuaa=_byte_vwuz1 lda {z1} //FRAGMENT vbuxx=_byte_vwuz1 @@ -4600,15 +4666,9 @@ beq {la1} //FRAGMENT _stackpushbyte_=vbuc1 lda #{c1} pha -//FRAGMENT _stackpullbyte_1 -pla //FRAGMENT vbuz1=_stackpullbyte_ pla sta {z1} -//FRAGMENT vbuz1=_stackidxbyte_vbuc1 -tsx -lda STACK_BASE+{c1},x -sta {z1} //FRAGMENT _stackidxbyte_vbuc1=vbuz1 lda {z1} tsx @@ -4621,17 +4681,6 @@ tax //FRAGMENT vbuyy=_stackpullbyte_ pla tay -//FRAGMENT vbuaa=_stackidxbyte_vbuc1 -tsx -lda STACK_BASE+{c1},x -//FRAGMENT vbuxx=_stackidxbyte_vbuc1 -tsx -lda STACK_BASE+{c1},x -tax -//FRAGMENT vbuyy=_stackidxbyte_vbuc1 -tsx -lda STACK_BASE+{c1},x -tay //FRAGMENT _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+{c1},x @@ -4773,84 +4822,136 @@ bne !+ dec {z1}+1 !: dec {z1} +//FRAGMENT vssz1=_stackidxstruct_2_vbuc1 +tsx +lda STACK_BASE+{c1},x +sta {z1} +lda STACK_BASE+{c1}+1,x +sta {z1}+1 +//FRAGMENT pbuc1_derefidx_vbuz1=_deref_pbuc2 +lda {c2} +ldy {z1} +sta {c1},y //FRAGMENT vbuz1=vbuz2_ror_1 lda {z2} lsr sta {z1} -//FRAGMENT _stackpushbyte_=vbuz1 +//FRAGMENT _stackidxstruct_2_vbuc1=vssz1 +tsx lda {z1} -pha +sta STACK_BASE+{c1},x +lda {z1}+1 +sta STACK_BASE+{c1}+1,x //FRAGMENT _stackpushbyte_1 pha +//FRAGMENT vssz1=_stackpullstruct_2_ +pla +sta {z1} +pla +sta {z1}+1 +//FRAGMENT _stackpushstruct_2_=vssz1 +lda {z1}+1 +pha +lda {z1} +pha //FRAGMENT _stackpullbyte_2 pla pla -//FRAGMENT vbuz1=vbuaa_ror_1 -lsr -sta {z1} -//FRAGMENT vbuz1=vbuxx_ror_1 -txa -lsr -sta {z1} -//FRAGMENT vbuz1=vbuyy_ror_1 -tya -lsr -sta {z1} //FRAGMENT vbuaa=vbuz1_ror_1 lda {z1} lsr -//FRAGMENT vbuaa=vbuaa_ror_1 -lsr -//FRAGMENT vbuaa=vbuxx_ror_1 -txa -lsr -//FRAGMENT vbuaa=vbuyy_ror_1 -tya -lsr //FRAGMENT vbuxx=vbuz1_ror_1 lda {z1} lsr tax -//FRAGMENT vbuxx=vbuaa_ror_1 -lsr -tax -//FRAGMENT vbuxx=vbuxx_ror_1 -txa -lsr -tax -//FRAGMENT vbuxx=vbuyy_ror_1 -tya -lsr -tax //FRAGMENT vbuyy=vbuz1_ror_1 lda {z1} lsr tay +//FRAGMENT vbuz1=vbuaa_ror_1 +lsr +sta {z1} +//FRAGMENT vbuaa=vbuaa_ror_1 +lsr +//FRAGMENT vbuxx=vbuaa_ror_1 +lsr +tax //FRAGMENT vbuyy=vbuaa_ror_1 lsr tay +//FRAGMENT vbuz1=vbuxx_ror_1 +txa +lsr +sta {z1} +//FRAGMENT vbuaa=vbuxx_ror_1 +txa +lsr +//FRAGMENT vbuxx=vbuxx_ror_1 +txa +lsr +tax //FRAGMENT vbuyy=vbuxx_ror_1 txa lsr tay +//FRAGMENT vbuz1=vbuyy_ror_1 +tya +lsr +sta {z1} +//FRAGMENT vbuaa=vbuyy_ror_1 +tya +lsr +//FRAGMENT vbuxx=vbuyy_ror_1 +tya +lsr +tax //FRAGMENT vbuyy=vbuyy_ror_1 tya lsr tay -//FRAGMENT _stackpushbyte_=vbuxx -txa -pha -//FRAGMENT _stackpushbyte_=vbuyy -tya -pha +//FRAGMENT vssz1=_stackidxstruct_vbuc1_vbuc2 +tsx +ldy #0 +!: +lda STACK_BASE+{c2},x +sta {z1},y +inx +iny +cpy #{c1} +bne !- //FRAGMENT vbuz1=vbuz2_plus_1 ldy {z2} iny sty {z1} +//FRAGMENT _stackidxstruct_vbuc1_vbuc2=vssz1 +tsx +ldy #0 +!: +lda {z1},y +sta STACK_BASE+{c2},x +inx +iny +cpy #{c1} +bne !- //FRAGMENT _stackpushbyte_3 pha pha pha +//FRAGMENT vssz1=_stackpullstruct_vbuc1_ +ldx #0 +!: +pla +sta {z1},x +inx +cpx #{c1} +bne !- +//FRAGMENT _stackpushstruct_vbuc1_=vssz1 +ldy #{c1} +!: +lda {z1}-1,y +pha +dey +bne !- //FRAGMENT _stackpullbyte_4 tsx txa @@ -4860,15 +4961,22 @@ txs lda {z1} clc adc #1 -//FRAGMENT vbuyy=vbuz1_plus_1 -ldy {z1} -iny +//FRAGMENT vbuxx=vbuz1_plus_1 +ldx {z1} +inx //FRAGMENT vbuz1=vbuxx_plus_1 inx stx {z1} //FRAGMENT vbuz1=vbuyy_plus_1 iny sty {z1} +//FRAGMENT vbuxx=vbuyy_plus_1 +tya +tax +inx +//FRAGMENT vbuyy=vbuz1_plus_1 +ldy {z1} +iny //FRAGMENT vbuyy=vbuxx_plus_1 txa tay @@ -4912,6 +5020,9 @@ pha //FRAGMENT vbuxx=vbuz1_minus_1 ldx {z1} dex +//FRAGMENT _stackpushbyte_=vbuxx +txa +pha //FRAGMENT vbuyy=vbuz1_minus_1 lda {z1} tay @@ -5222,9 +5333,6 @@ asl {z1} rol {z1}+1 asl {z1} rol {z1}+1 -//FRAGMENT 0_eq_vbuaa_then_la1 -cmp #0 -beq {la1} //FRAGMENT vbuz1=vbuaa_plus_1 clc adc #1 @@ -6185,9 +6293,6 @@ bcs {la1} sty $ff cpx $ff bcc {la1} -//FRAGMENT vbuxx=vbuz1_plus_1 -ldx {z1} -inx //FRAGMENT vwuz1=vwuz1_rol_1 asl {z1} rol {z1}+1 @@ -6683,14 +6788,6 @@ sta {z1} lda {z1}+1 eor {z2}+1 sta {z1}+1 -//FRAGMENT vwuz1=vwuz1_plus_vbuxx -txa -clc -adc {z1} -sta {z1} -bcc !+ -inc {z1}+1 -!: //FRAGMENT _deref_pbuc1=_byte_vwuz1 lda {z1} sta {c1} @@ -8317,15 +8414,6 @@ NO_SYNTHESIS NO_SYNTHESIS //FRAGMENT vduz1=_makelong4_(vbuyy)_(vbuyy)_(vbuyy)_(vbuyy) NO_SYNTHESIS -//FRAGMENT _deref_pduc1=vduc2 -lda #<{c2} -sta {c1} -lda #>{c2} -sta {c1}+1 -lda #<{c2}>>$10 -sta {c1}+2 -lda #>{c2}>>$10 -sta {c1}+3 //FRAGMENT isr_rom_sys_c64_entry //FRAGMENT pbuz1_derefidx_vbuz2=_inc_pbuz1_derefidx_vbuz2 @@ -8374,10 +8462,6 @@ txa //FRAGMENT vbuaa=vbuyy_plus_1 iny tya -//FRAGMENT vbuxx=vbuyy_plus_1 -tya -tax -inx //FRAGMENT pssz1=pssc1_plus_vbuz2 lda {z2} clc @@ -9293,6 +9377,17 @@ lda {c1} sta {z1} lda {c1}+1 sta {z1}+1 +//FRAGMENT vbuz1=_byte_vwsz2 +lda {z2} +sta {z1} +//FRAGMENT vbuaa=_byte_vwsz1 +lda {z1} +//FRAGMENT vbuxx=_byte_vwsz1 +lda {z1} +tax +//FRAGMENT vbuyy=_byte_vwsz1 +lda {z1} +tay //FRAGMENT vbsz1=vbsz2 lda {z2} sta {z1} @@ -11407,17 +11502,6 @@ bvc !+ eor #$80 !: bpl {la1} -//FRAGMENT vbuz1=_byte_vwsz2 -lda {z2} -sta {z1} -//FRAGMENT vbuaa=_byte_vwsz1 -lda {z1} -//FRAGMENT vbuxx=_byte_vwsz1 -lda {z1} -tax -//FRAGMENT vbuyy=_byte_vwsz1 -lda {z1} -tay //FRAGMENT vbuz1=_deref_pbuc1_plus_1 ldy {c1} iny @@ -12584,11 +12668,6 @@ lda ({z1}),y tay lda {c2},y sta {c1},x -//FRAGMENT _deref_pwuc1=vbuc2 -lda #<{c2} -sta {c1} -lda #>{c2} -sta {c1}+1 //FRAGMENT qssz1=qssc1_plus_vwsz2 clc lda #<{c1} @@ -12746,6 +12825,9 @@ bne {la1} lda {z2} ldy #0 sta ({z1}),y +//FRAGMENT _deref_pbuc1=_byte_pprz1 +lda {z1} +sta {c1} //FRAGMENT vbuz1=vbuz2_band_pbuz3_derefidx_vbuc1 lda {z2} ldy #{c1} @@ -13124,10 +13206,6 @@ tya clc adc {m1} sta {m1} -//FRAGMENT pbuc1_derefidx_vbuz1=_deref_pbuc2 -lda {c2} -ldy {z1} -sta {c1},y //FRAGMENT _deref_pbuc1=_deref_pbuc1_plus_vbuz1 lda {c1} clc @@ -14340,14 +14418,6 @@ sta {z1} bcc !+ inc {z1}+1 !: -//FRAGMENT vwuz1=vwuz1_plus_vbuyy -tya -clc -adc {z1} -sta {z1} -bcc !+ -inc {z1}+1 -!: //FRAGMENT _deref_pbuc1=_deref_(_deref_qbuc2) ldy {c2} sty $fe @@ -15265,16 +15335,3 @@ sta {c1},x lda #{c2} ora {c1},y sta {c1},y -//FRAGMENT vwuz1=vwuz2_ror_8 -lda {z2}+1 -sta {z1} -lda #0 -sta {z1}+1 -//FRAGMENT vwuz1=vwuz1_ror_8 -lda {z1}+1 -sta {z1} -lda #0 -sta {z1}+1 -//FRAGMENT vbuaa_eq_vbuz1_then_la1 -cmp {z1} -beq {la1} diff --git a/src/main/fragment/cache/fragment-cache-rom6502x.asm b/src/main/fragment/cache/fragment-cache-rom6502x.asm index 5a0a9f7d1..e8d345317 100644 --- a/src/main/fragment/cache/fragment-cache-rom6502x.asm +++ b/src/main/fragment/cache/fragment-cache-rom6502x.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 9a29ecc94 9a29eec1a +//KICKC FRAGMENT CACHE 8c8c73a6a 8c8c75a58 //FRAGMENT _deref_pbuc1=_inc__deref_pbuc1 inc {c1} //FRAGMENT isr_hardware_all_entry diff --git a/src/main/fragment/cache/fragment-cache-wdc65c02.asm b/src/main/fragment/cache/fragment-cache-wdc65c02.asm index bea3ca092..2fa3a4122 100644 --- a/src/main/fragment/cache/fragment-cache-wdc65c02.asm +++ b/src/main/fragment/cache/fragment-cache-wdc65c02.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 9a29ecc94 9a29eec1a +//KICKC FRAGMENT CACHE 8c8c73a6a 8c8c75a58 //FRAGMENT vbuz1=_deref_pbuc1 lda {c1} sta {z1} diff --git a/src/main/fragment/mos6502-common/_stackidxstruct_1_vbuc1=vssm1.asm b/src/main/fragment/mos6502-common/_stackidxstruct_1_vbuc1=vssm1.asm new file mode 100644 index 000000000..49deaaf0d --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackidxstruct_1_vbuc1=vssm1.asm @@ -0,0 +1,3 @@ +tsx +lda {m1} +sta STACK_BASE+{c1},x \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackidxstruct_2_vbuc1=vssm1.asm b/src/main/fragment/mos6502-common/_stackidxstruct_2_vbuc1=vssm1.asm new file mode 100644 index 000000000..b94f7df12 --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackidxstruct_2_vbuc1=vssm1.asm @@ -0,0 +1,5 @@ +tsx +lda {m1} +sta STACK_BASE+{c1},x +lda {m1}+1 +sta STACK_BASE+{c1}+1,x \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackidxstruct_3_vbuc1=vssm1.asm b/src/main/fragment/mos6502-common/_stackidxstruct_3_vbuc1=vssm1.asm new file mode 100644 index 000000000..c7ec754bb --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackidxstruct_3_vbuc1=vssm1.asm @@ -0,0 +1,7 @@ +tsx +lda {m1} +sta STACK_BASE+{c1},x +lda {m1}+1 +sta STACK_BASE+{c1}+1,x +lda {m1}+2 +sta STACK_BASE+{c1}+2,x \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackidxstruct_4_vbuc1=vssm1.asm b/src/main/fragment/mos6502-common/_stackidxstruct_4_vbuc1=vssm1.asm new file mode 100644 index 000000000..1f8892c24 --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackidxstruct_4_vbuc1=vssm1.asm @@ -0,0 +1,9 @@ +tsx +lda {m1} +sta STACK_BASE+{c1},x +lda {m1}+1 +sta STACK_BASE+{c1}+1,x +lda {m1}+2 +sta STACK_BASE+{c1}+2,x +lda {m1}+3 +sta STACK_BASE+{c1}+3,x \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackidxstruct_vbuc1_vbuc2=vssm1.asm b/src/main/fragment/mos6502-common/_stackidxstruct_vbuc1_vbuc2=vssm1.asm new file mode 100644 index 000000000..4c596f903 --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackidxstruct_vbuc1_vbuc2=vssm1.asm @@ -0,0 +1,9 @@ +tsx +ldy #0 +!: +lda {m1},y +sta STACK_BASE+{c2},x +inx +iny +cpy #{c1} +bne !- \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackidxword_vbuc1=vwum1.asm b/src/main/fragment/mos6502-common/_stackidxword_vbuc1=vwum1.asm index 31c57a844..b94f7df12 100644 --- a/src/main/fragment/mos6502-common/_stackidxword_vbuc1=vwum1.asm +++ b/src/main/fragment/mos6502-common/_stackidxword_vbuc1=vwum1.asm @@ -2,4 +2,4 @@ tsx lda {m1} sta STACK_BASE+{c1},x lda {m1}+1 -sta STACK_BASE+{c1}+1,x +sta STACK_BASE+{c1}+1,x \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackpushstruct_1_=vssm1.asm b/src/main/fragment/mos6502-common/_stackpushstruct_1_=vssm1.asm new file mode 100644 index 000000000..713d1d32c --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackpushstruct_1_=vssm1.asm @@ -0,0 +1,2 @@ +lda {m1} +pha \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackpushstruct_2_=vssm1.asm b/src/main/fragment/mos6502-common/_stackpushstruct_2_=vssm1.asm new file mode 100644 index 000000000..16e7f80f6 --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackpushstruct_2_=vssm1.asm @@ -0,0 +1,4 @@ +lda {m1}+1 +pha +lda {m1} +pha \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackpushstruct_3_=vssm1.asm b/src/main/fragment/mos6502-common/_stackpushstruct_3_=vssm1.asm new file mode 100644 index 000000000..56536a6d3 --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackpushstruct_3_=vssm1.asm @@ -0,0 +1,6 @@ +lda {m1}+2 +pha +lda {m1}+1 +pha +lda {m1} +pha \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackpushstruct_4_=vssm1.asm b/src/main/fragment/mos6502-common/_stackpushstruct_4_=vssm1.asm new file mode 100644 index 000000000..81c35b07a --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackpushstruct_4_=vssm1.asm @@ -0,0 +1,8 @@ +lda {m1}+3 +pha +lda {m1}+2 +pha +lda {m1}+1 +pha +lda {m1} +pha \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/_stackpushstruct_vbuyy_=vssm1.asm b/src/main/fragment/mos6502-common/_stackpushstruct_vbuyy_=vssm1.asm new file mode 100644 index 000000000..d3184e94f --- /dev/null +++ b/src/main/fragment/mos6502-common/_stackpushstruct_vbuyy_=vssm1.asm @@ -0,0 +1,5 @@ +!: +lda {m1}-1,y +pha +dey +bne !- diff --git a/src/main/fragment/mos6502-common/_stackpushsword_=vwsm1.asm b/src/main/fragment/mos6502-common/_stackpushsword_=vwsm1.asm index 63b51bce2..16e7f80f6 100644 --- a/src/main/fragment/mos6502-common/_stackpushsword_=vwsm1.asm +++ b/src/main/fragment/mos6502-common/_stackpushsword_=vwsm1.asm @@ -1,4 +1,4 @@ lda {m1}+1 pha lda {m1} -pha +pha \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_1_vbuc1.asm b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_1_vbuc1.asm new file mode 100644 index 000000000..c930f49b2 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_1_vbuc1.asm @@ -0,0 +1,3 @@ +tsx +lda STACK_BASE+{c1},x +sta {m1} \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_2_vbuc1.asm b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_2_vbuc1.asm new file mode 100644 index 000000000..b2132b318 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_2_vbuc1.asm @@ -0,0 +1,5 @@ +tsx +lda STACK_BASE+{c1},x +sta {m1} +lda STACK_BASE+{c1}+1,x +sta {m1}+1 \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_3_vbuc1.asm b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_3_vbuc1.asm new file mode 100644 index 000000000..86af7babe --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_3_vbuc1.asm @@ -0,0 +1,7 @@ +tsx +lda STACK_BASE+{c1},x +sta {m1} +lda STACK_BASE+{c1}+1,x +sta {m1}+1 +lda STACK_BASE+{c1}+2,x +sta {m1}+2 \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_4_vbuc1.asm b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_4_vbuc1.asm new file mode 100644 index 000000000..31fad1e8d --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_4_vbuc1.asm @@ -0,0 +1,9 @@ +tsx +lda STACK_BASE+{c1},x +sta {m1} +lda STACK_BASE+{c1}+1,x +sta {m1}+1 +lda STACK_BASE+{c1}+2,x +sta {m1}+2 +lda STACK_BASE+{c1}+3,x +sta {m1}+3 \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_vbuc1_vbuc2.asm b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_vbuc1_vbuc2.asm new file mode 100644 index 000000000..356302334 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackidxstruct_vbuc1_vbuc2.asm @@ -0,0 +1,9 @@ +tsx +ldy #0 +!: +lda STACK_BASE+{c2},x +sta {m1},y +inx +iny +cpy #{c1} +bne !- \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_1_.asm b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_1_.asm new file mode 100644 index 000000000..66c22a6c1 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_1_.asm @@ -0,0 +1,2 @@ +pla +sta {m1} \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_2_.asm b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_2_.asm new file mode 100644 index 000000000..abbb39fb6 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_2_.asm @@ -0,0 +1,4 @@ +pla +sta {m1} +pla +sta {m1}+1 \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_3_.asm b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_3_.asm new file mode 100644 index 000000000..db145ea26 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_3_.asm @@ -0,0 +1,6 @@ +pla +sta {m1} +pla +sta {m1}+1 +pla +sta {m1}+2 \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_4_.asm b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_4_.asm new file mode 100644 index 000000000..e88bd1fd8 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_4_.asm @@ -0,0 +1,8 @@ +pla +sta {m1} +pla +sta {m1}+1 +pla +sta {m1}+2 +pla +sta {m1}+3 \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_vbuc1_.asm b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_vbuc1_.asm new file mode 100644 index 000000000..3292dc405 --- /dev/null +++ b/src/main/fragment/mos6502-common/vssm1=_stackpullstruct_vbuc1_.asm @@ -0,0 +1,7 @@ +ldx #0 +!: +pla +sta {m1},x +inx +cpx #{c1} +bne !- \ No newline at end of file diff --git a/src/main/fragment/mos6502-common/vwum1=_stackidxword_vbuc1.asm b/src/main/fragment/mos6502-common/vwum1=_stackidxword_vbuc1.asm index fb56042f3..b2132b318 100644 --- a/src/main/fragment/mos6502-common/vwum1=_stackidxword_vbuc1.asm +++ b/src/main/fragment/mos6502-common/vwum1=_stackidxword_vbuc1.asm @@ -2,4 +2,4 @@ tsx lda STACK_BASE+{c1},x sta {m1} lda STACK_BASE+{c1}+1,x -sta {m1}+1 +sta {m1}+1 \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java index 691290fc3..c0c66243c 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java @@ -11,6 +11,7 @@ import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.*; +import dk.camelot64.kickc.passes.utils.SizeOfConstants; import java.lang.InternalError; import java.util.HashMap; @@ -127,6 +128,7 @@ public class AsmFragmentInstanceSpecBuilder { /** * MAKELONG4() creates a long form 4 bytes + * * @param call The intrinsic call * @param program The program * @return The ASM fragment instance @@ -142,7 +144,7 @@ public class AsmFragmentInstanceSpecBuilder { signature.append(bind(make4long.getlValue())); signature.append("="); signature.append("_makelong4_("); - if(make4long.getParameters().size()!=4) + if(make4long.getParameters().size() != 4) throw new CompileError("MAKELONG4() needs 4 parameters.", make4long); signature.append(bind(make4long.getParameter(3))); signature.append(")_("); @@ -279,7 +281,7 @@ public class AsmFragmentInstanceSpecBuilder { } else if( rValue2 instanceof ConstantInteger && ((ConstantInteger) rValue2).getValue() == 0 && - (Operators.MINUS.equals(operator) || Operators.PLUS.equals(operator)) ) { + (Operators.MINUS.equals(operator) || Operators.PLUS.equals(operator))) { signature.append("0"); } else { signature.append(bind(rValue2)); @@ -475,15 +477,15 @@ public class AsmFragmentInstanceSpecBuilder { StackIdxValue stackIdxValue = (StackIdxValue) value; SymbolType type = stackIdxValue.getValueType(); String typeShortName = Operators.getCastUnary(type).getAsmOperator().replace("_", ""); - return "_stackidx" + typeShortName + "_" + bind(stackIdxValue.getStackOffset()); + return "_stackidx" + typeShortName + bindStructSize(type) + "_" + bind(stackIdxValue.getStackOffset()); } else if(value instanceof StackPushValue) { SymbolType type = ((StackPushValue) value).getType(); String typeShortName = Operators.getCastUnary(type).getAsmOperator().replace("_", ""); - return "_stackpush" + typeShortName + "_"; + return "_stackpush" + typeShortName + bindStructSize(type) + "_"; } else if(value instanceof StackPullValue) { SymbolType type = ((StackPullValue) value).getType(); String typeShortName = Operators.getCastUnary(type).getAsmOperator().replace("_", ""); - return "_stackpull" + typeShortName + "_"; + return "_stackpull" + typeShortName + bindStructSize(type) + "_"; } else if(value instanceof StackPullBytes) { final ConstantInteger bytes = (ConstantInteger) ((StackPullBytes) value).getBytes(); return "_stackpullbyte_" + AsmFormat.getAsmNumber(bytes.getInteger()); @@ -510,6 +512,23 @@ public class AsmFragmentInstanceSpecBuilder { throw new RuntimeException("Binding of value type not supported " + value.toString(program)); } + /** + * Binds the struct size (if the type is a struct.) + * + * @param type The type + * @return The bind name + */ + private String bindStructSize(SymbolType type) { + if(type instanceof SymbolTypeStruct) { + ConstantRef sizeConst = SizeOfConstants.getSizeOfConstantVar(program.getScope(), type); + ConstantLiteral literal = sizeConst.calculateLiteral(program.getScope()); + if(literal instanceof ConstantInteger && ((ConstantInteger) literal).getInteger() <= 4L) + return "_" + ((ConstantInteger) literal).getInteger(); + return "_" + bind(sizeConst); + } + return ""; + } + /** * Add binding for a name/value pair if it is not already bound. * diff --git a/src/main/java/dk/camelot64/kickc/model/CallGraph.java b/src/main/java/dk/camelot64/kickc/model/CallGraph.java index 7aa3a6bde..2451dcac9 100644 --- a/src/main/java/dk/camelot64/kickc/model/CallGraph.java +++ b/src/main/java/dk/camelot64/kickc/model/CallGraph.java @@ -138,9 +138,9 @@ public class CallGraph { Collection callers = new ArrayList<>(); for(CallBlock callBlock : callBlocks) { for(CallBlock.Call call : callBlock.getCalls()) { - if(call.getProcedure().equals(procedureRef)) { - callers.add(call); - } + if(call.getProcedure()!=null) + if(call.getProcedure().equals(procedureRef)) + callers.add(call); } } return callers; @@ -183,9 +183,10 @@ public class CallGraph { Collection callers = new ArrayList<>(); for(CallBlock callBlock : callBlocks) { for(CallBlock.Call call : callBlock.getCalls()) { - if(call.getProcedure().equals(label)) { - callers.add(callBlock.getScopeLabel()); - } + if(call.getProcedure()!=null) + if(call.getProcedure().equals(label)) { + callers.add(callBlock.getScopeLabel()); + } } } return callers; @@ -267,7 +268,8 @@ public class CallGraph { public Collection getCalledBlocks() { LinkedHashSet called = new LinkedHashSet<>(); for(Call call : calls) { - called.add(call.getProcedure()); + if(call.getProcedure()!=null) + called.add(call.getProcedure()); } return called; } @@ -300,8 +302,10 @@ public class CallGraph { public Collection getCalls(ScopeRef scope) { ArrayList callsToScope = new ArrayList<>(); for(Call call : calls) { - if(call.getProcedure().equals(scope)) { - callsToScope.add(call); + if(call.getProcedure()!=null) { + if(call.getProcedure().equals(scope)) { + callsToScope.add(call); + } } } return callsToScope; diff --git a/src/main/java/dk/camelot64/kickc/model/CallingConventionStack.java b/src/main/java/dk/camelot64/kickc/model/CallingConventionStack.java index 1a812d61f..675b6e0a6 100644 --- a/src/main/java/dk/camelot64/kickc/model/CallingConventionStack.java +++ b/src/main/java/dk/camelot64/kickc/model/CallingConventionStack.java @@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantRef; @@ -20,7 +21,7 @@ public class CallingConventionStack { public static final String OFFSET_STACK = "OFFSET_STACK_"; /** Name of the constant holding the stack offset for the return value. */ - public static final String OFFSET_STACK_RETURN = OFFSET_STACK + "RETURN"; + public static final String OFFSET_STACK_RETURN = OFFSET_STACK + "RETURN_"; /** * Get the name of the constant variable containing the (byte) offset of a specific parameter on the stack @@ -35,16 +36,17 @@ public class CallingConventionStack { /** * Get the constant variable containing the (byte) index of the return value on the stack * - * @param procedure The procedure + * @param procedureType The procedure type * @return The return value stack offset constant */ - public static ConstantRef getReturnOffsetConstant(Procedure procedure) { - Variable returnOffsetConstant = procedure.getLocalConstant(OFFSET_STACK_RETURN); + public static ConstantRef getReturnOffsetConstant(SymbolTypeProcedure procedureType, Scope scope) { + long returnByteOffset = getReturnByteOffset(procedureType); + String offsetConstName = OFFSET_STACK_RETURN+returnByteOffset; + Variable returnOffsetConstant = scope.getLocalConstant(offsetConstName); if(returnOffsetConstant == null) { // Constant not found - create it - long returnByteOffset = getReturnByteOffset(procedure); - returnOffsetConstant = Variable.createConstant(OFFSET_STACK_RETURN, SymbolType.BYTE, procedure, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT); - procedure.add(returnOffsetConstant); + returnOffsetConstant = Variable.createConstant(offsetConstName, SymbolType.BYTE, scope, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT); + scope.add(returnOffsetConstant); } return returnOffsetConstant.getConstantRef(); } @@ -71,13 +73,13 @@ public class CallingConventionStack { /** * Get the number of bytes that needed on the stack to pass parameters/return value to/from a procedure * - * @param procedure The procedure to find the stack frame size for + * @param procedureType The procedure type to find the stack frame size for * @return The byte size of the stack frame */ - public static long getStackFrameByteSize(Procedure procedure) { - long byteSize = getParametersByteSize(procedure); - if(procedure.getReturnType() != null) { - int returnBytes = procedure.getReturnType().getSizeBytes(); + public static long getStackFrameByteSize(SymbolTypeProcedure procedureType) { + long byteSize = getParametersByteSize(procedureType); + if(procedureType.getReturnType() != null) { + int returnBytes = procedureType.getReturnType().getSizeBytes(); if(returnBytes > byteSize) byteSize = returnBytes; } return byteSize; @@ -86,13 +88,13 @@ public class CallingConventionStack { /** * Get the number of bytes needed on the stack to store the parameters from a procedure * - * @param procedure The procedure + * @param procedureType The procedure type * @return The byte size of parameters */ - public static long getParametersByteSize(Procedure procedure) { + public static long getParametersByteSize(SymbolTypeProcedure procedureType) { long byteSize = 0; - for(Variable procedureParameter : procedure.getParameters()) { - byteSize += procedureParameter.getType().getSizeBytes(); + for(SymbolType paramType : procedureType.getParamTypes()) { + byteSize += paramType.getSizeBytes(); } return byteSize; } @@ -122,11 +124,11 @@ public class CallingConventionStack { /** * Get the number of bytes that the return value is offset on the stack * - * @param procedure The procedure + * @param procedureType The procedure type * @return The byte offset of the return value */ - private static long getReturnByteOffset(Procedure procedure) { - return getStackFrameByteSize(procedure) - procedure.getReturnType().getSizeBytes(); + private static long getReturnByteOffset(SymbolTypeProcedure procedureType) { + return getStackFrameByteSize(procedureType) - procedureType.getReturnType().getSizeBytes(); } /** diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java index 2018e84e5..0c7126602 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java @@ -75,6 +75,25 @@ public interface ProgramValue { } } + class CallExecuteProcedure implements ProgramValue { + private final StatementCallExecute call; + + CallExecuteProcedure(StatementCallExecute call) { + this.call = call; + } + + @Override + public Value get() { + return call.getProcedureRVal(); + } + + @Override + public void set(Value value) { + call.setProcedureRVal((RValue) value); + } + } + + class CallParameter implements ProgramValue { private final StatementCall call; private final int i; @@ -328,7 +347,7 @@ public interface ProgramValue { } @Override - public void set(Value value) { + public void set(Value value) { statementExprSideEffect.setExpression((RValue) value); } diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java index 700511f58..9f2ba2c37 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java @@ -133,6 +133,8 @@ public class ProgramValueIterator { execute(new ProgramValue.CallPrepareParameter(call, i), handler, statement, statementsIt, block); } } + } else if(statement instanceof StatementCallExecute) { + execute(new ProgramValue.CallExecuteProcedure((StatementCallExecute) statement), handler, statement, statementsIt, block); } else if(statement instanceof StatementCallFinalize) { execute(new ProgramValue.ProgramValueLValue((StatementLValue) statement), handler, statement, statementsIt, block); } else if(statement instanceof StatementCallPointer) { diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementCallExecute.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementCallExecute.java index 4bf770188..f1f54fe05 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementCallExecute.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementCallExecute.java @@ -2,7 +2,10 @@ package dk.camelot64.kickc.model.statements; import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.ProcedureRef; +import dk.camelot64.kickc.model.values.RValue; import java.util.List; import java.util.Objects; @@ -16,15 +19,34 @@ import java.util.Objects; */ public class StatementCallExecute extends StatementBase implements StatementCalling { - /** The procedure called. */ - private ProcedureRef procedure; + /** The procedure called (if this is a call to a specific procedure). Null if this is a pointer-based call. */ + private RValue procedure; - public StatementCallExecute(ProcedureRef procedure, StatementSource source, List comments) { + /** The type of the procedure. */ + private SymbolTypeProcedure procedureType; + + /** The calling convention to use. */ + private Procedure.CallingConvention callingConvention; + + public StatementCallExecute(SymbolTypeProcedure procedureType, RValue procedure, Procedure.CallingConvention callingConvention, StatementSource source, List comments) { super(source, comments); + this.procedureType = procedureType; this.procedure = procedure; + this.callingConvention = callingConvention; + } + + public SymbolTypeProcedure getProcedureType() { + return procedureType; } public ProcedureRef getProcedure() { + if(procedure instanceof ProcedureRef) + return (ProcedureRef) procedure; + else + return null; + } + + public RValue getProcedureRVal() { return procedure; } @@ -32,14 +54,21 @@ public class StatementCallExecute extends StatementBase implements StatementCall this.procedure = procedure; } + public void setProcedureRVal(RValue procedure) { + this.procedure = procedure; + } + + + public Procedure.CallingConvention getCallingConvention() { + return callingConvention; + } + @Override public String toString(Program program, boolean aliveInfo) { StringBuilder res = new StringBuilder(); res.append(super.idxString()); res.append("callexecute "); - if(procedure != null) { - res.append(procedure.getFullName() + " "); - } + res.append(procedure.toString(null) + " "); if(aliveInfo) { res.append(super.aliveString(program)); } diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementCallFinalize.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementCallFinalize.java index 859f3bcfd..0582da487 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementCallFinalize.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementCallFinalize.java @@ -2,6 +2,8 @@ package dk.camelot64.kickc.model.statements; import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.LValue; import dk.camelot64.kickc.model.values.ProcedureRef; @@ -17,17 +19,26 @@ import java.util.Objects; */ public class StatementCallFinalize extends StatementBase implements StatementLValue { + /** The procedure called (if this is a call to a specific procedure). Null if this is a pointer-based call. */ + private ProcedureRef procedure; + + /** The type of the procedure. */ + private SymbolTypeProcedure procedureType; + + /** The calling convention to use. */ + private Procedure.CallingConvention callingConvention; + /** The variable being assigned a value by the call. Can be null. */ private LValue lValue; - /** The procedure called. */ - private ProcedureRef procedure; /** This is the initial assignment of the lValue. */ private boolean initialAssignment; - public StatementCallFinalize(LValue lValue, ProcedureRef procedure, StatementSource source, List comments) { + public StatementCallFinalize(LValue lValue, SymbolTypeProcedure procedureType, ProcedureRef procedure, Procedure.CallingConvention callingConvention, StatementSource source, List comments) { super(source, comments); this.lValue = lValue; this.procedure = procedure; + this.procedureType = procedureType; + this.callingConvention = callingConvention; } public LValue getlValue() { @@ -46,6 +57,14 @@ public class StatementCallFinalize extends StatementBase implements StatementLVa this.procedure = procedure; } + public SymbolTypeProcedure getProcedureType() { + return procedureType; + } + + public Procedure.CallingConvention getCallingConvention() { + return callingConvention; + } + @Override public boolean isInitialAssignment() { return initialAssignment; diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementCallPrepare.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementCallPrepare.java index 8b19f58f2..2280e935f 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementCallPrepare.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementCallPrepare.java @@ -2,6 +2,8 @@ package dk.camelot64.kickc.model.statements; import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.ProcedureRef; import dk.camelot64.kickc.model.values.RValue; @@ -17,15 +19,28 @@ import java.util.Objects; */ public class StatementCallPrepare extends StatementBase { - /** The procedure called. */ + /** The procedure called (if this is a call to a specific procedure). Null if this is a pointer-based call. */ private ProcedureRef procedure; + + /** The type of the procedure. */ + private SymbolTypeProcedure procedureType; + + /** The calling convention to use. */ + private Procedure.CallingConvention callingConvention; + /** The parameter values passed to the procedure. */ private List parameters; - public StatementCallPrepare(ProcedureRef procedure, List parameters, StatementSource source, List comments) { + public StatementCallPrepare(SymbolTypeProcedure procedureType, ProcedureRef procedure, List parameters, Procedure.CallingConvention callingConvention, StatementSource source, List comments) { super(source, comments); + this.procedureType = procedureType; this.procedure = procedure; this.parameters = parameters; + this.callingConvention = callingConvention; + } + + public SymbolTypeProcedure getProcedureType() { + return procedureType; } public ProcedureRef getProcedure() { @@ -52,6 +67,10 @@ public class StatementCallPrepare extends StatementBase { return parameters.get(idx); } + public Procedure.CallingConvention getCallingConvention() { + return callingConvention; + } + @Override public String toString(Program program, boolean aliveInfo) { StringBuilder res = new StringBuilder(); diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java index d1bbb91c0..14a8990ac 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java @@ -184,7 +184,7 @@ public class Procedure extends Scope { } @Override - public SymbolType getType() { + public SymbolTypeProcedure getType() { return procedureType; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfHandling.java b/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfHandling.java index 2f77d9ca3..03d737cdf 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfHandling.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfHandling.java @@ -76,10 +76,10 @@ public class Pass1AddressOfHandling extends Pass2SsaOptimization { } } } else if(toSymbol instanceof Procedure) { - if(((Procedure) toSymbol).getParameters().size() > 0) { - ((Procedure) toSymbol).setCallingConvention(Procedure.CallingConvention.STACK_CALL); + Procedure procedure = (Procedure) toSymbol; + if(procedure.getParameters().size() > 0 || !SymbolType.VOID.equals(procedure.getReturnType())) { + procedure.setCallingConvention(Procedure.CallingConvention.STACK_CALL); getLog().append("Setting inferred __stackcall on procedure affected by address-of " + toSymbol.toString(getProgram()) + " caused by statement " + stmtStr); - ; } } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1CallStack.java b/src/main/java/dk/camelot64/kickc/passes/Pass1CallStack.java index a07b5d08d..b466021a2 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1CallStack.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1CallStack.java @@ -13,6 +13,7 @@ import dk.camelot64.kickc.model.symbols.StructDefinition; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.types.SymbolTypeStruct; import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.passes.utils.SizeOfConstants; @@ -43,7 +44,7 @@ public class Pass1CallStack extends Pass2SsaOptimization { } // Introduce the return value offset if(procedure.getReturnType() != null && !SymbolType.VOID.equals(procedure.getReturnType())) { - CallingConventionStack.getReturnOffsetConstant(procedure); + CallingConventionStack.getReturnOffsetConstant(procedure.getType(), procedure); createStackBase = true; } } @@ -81,7 +82,7 @@ public class Pass1CallStack extends Pass2SsaOptimization { Procedure procedure = (Procedure) blockScope; final SymbolType returnType = procedure.getReturnType(); if(!SymbolType.VOID.equals(returnType) && Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) { - ConstantRef returnOffsetConstant = CallingConventionStack.getReturnOffsetConstant(procedure); + ConstantRef returnOffsetConstant = CallingConventionStack.getReturnOffsetConstant(procedure.getType(), procedure); final RValue value = ((StatementReturn) statement).getValue(); stmtIt.previous(); generateStackReturnValues(value, returnType, returnOffsetConstant, statement.getSource(), statement.getComments(), stmtIt); @@ -100,11 +101,11 @@ public class Pass1CallStack extends Pass2SsaOptimization { Statement statement = stmtIt.next(); if(statement instanceof StatementCallFinalize) { final StatementCallFinalize call = (StatementCallFinalize) statement; - Procedure procedure = getScope().getProcedure(call.getProcedure()); - final SymbolType returnType = procedure.getReturnType(); - if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) { - long stackFrameByteSize = CallingConventionStack.getStackFrameByteSize(procedure); - long returnByteSize = procedure.getReturnType() == null ? 0 : procedure.getReturnType().getSizeBytes(); + SymbolTypeProcedure procedureType = call.getProcedureType(); + final SymbolType returnType = procedureType.getReturnType(); + if(Procedure.CallingConvention.STACK_CALL.equals(call.getCallingConvention())) { + long stackFrameByteSize = CallingConventionStack.getStackFrameByteSize(procedureType); + long returnByteSize = procedureType.getReturnType() == null ? 0 : procedureType.getReturnType().getSizeBytes(); long stackCleanBytes = (call.getlValue() == null) ? stackFrameByteSize : (stackFrameByteSize - returnByteSize); stmtIt.previous(); final StatementSource source = call.getSource(); @@ -130,22 +131,21 @@ public class Pass1CallStack extends Pass2SsaOptimization { Statement statement = stmtIt.next(); if(statement instanceof StatementCallPrepare) { final StatementCallPrepare call = (StatementCallPrepare) statement; - Procedure procedure = getScope().getProcedure(call.getProcedure()); - if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) { + if(Procedure.CallingConvention.STACK_CALL.equals(call.getCallingConvention())) { stmtIt.previous(); final StatementSource source = call.getSource(); List comments = call.getComments(); - final List parameterDefs = procedure.getParameters(); - for(int i=0;i paramTypes = call.getProcedureType().getParamTypes(); + for(int i=0;i parametersByteSize) { // Add padding to the stack to make room for the return value diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1CallStackVarConvert.java b/src/main/java/dk/camelot64/kickc/passes/Pass1CallStackVarConvert.java index 244953165..77705df45 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1CallStackVarConvert.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1CallStackVarConvert.java @@ -6,6 +6,8 @@ import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.*; import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.ProcedureRef; import java.util.ListIterator; @@ -29,15 +31,29 @@ public class Pass1CallStackVarConvert extends Pass2SsaOptimization { StatementCall call = (StatementCall) statement; ProcedureRef procedureRef = call.getProcedure(); Procedure procedure = getScope().getProcedure(procedureRef); - if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention()) || Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) { - boolean hasPrepare = (call.getParameters().size() > 0) || !SymbolType.VOID.equals(procedure.getReturnType()); + Procedure.CallingConvention callingConvention = procedure.getCallingConvention(); + if(Procedure.CallingConvention.STACK_CALL.equals(callingConvention) || Procedure.CallingConvention.VAR_CALL.equals(callingConvention)) { + boolean hasParamOrReturn = (call.getParameters().size() > 0) || !SymbolType.VOID.equals(procedure.getReturnType()); stmtIt.remove(); - stmtIt.add(new StatementCallPrepare(procedureRef, call.getParameters(), call.getSource(), hasPrepare?call.getComments():Comment.NO_COMMENTS)); - stmtIt.add(new StatementCallExecute(procedureRef, call.getSource(), hasPrepare?Comment.NO_COMMENTS:call.getComments())); - stmtIt.add(new StatementCallFinalize(call.getlValue(), procedureRef, call.getSource(), Comment.NO_COMMENTS)); - getLog().append("Calling convention " + procedure.getCallingConvention().getName() + " adding prepare/execute/finalize for " + call.toString(getProgram(), false)); + stmtIt.add(new StatementCallPrepare(procedure.getType(), procedureRef, call.getParameters(), callingConvention, call.getSource(), hasParamOrReturn?call.getComments():Comment.NO_COMMENTS)); + stmtIt.add(new StatementCallExecute(procedure.getType(), procedureRef, callingConvention, call.getSource(), hasParamOrReturn?Comment.NO_COMMENTS:call.getComments())); + stmtIt.add(new StatementCallFinalize(call.getlValue(), procedure.getType(), procedureRef, callingConvention, call.getSource(), Comment.NO_COMMENTS)); + getLog().append("Calling convention " + callingConvention.getName() + " adding prepare/execute/finalize for " + call.toString(getProgram(), false)); } + } else if(statement instanceof StatementCallPointer) { + StatementCallPointer call = (StatementCallPointer) statement; + boolean hasParamOrReturn = call.getNumParameters() > 0 || call.getlValue() != null; + //if(hasParamOrReturn) { + SymbolTypeProcedure procedureType = (SymbolTypeProcedure) SymbolTypeInference.inferType(getScope(), call.getProcedure()); + // Perform stack call + stmtIt.remove(); + stmtIt.add(new StatementCallPrepare(procedureType, null, call.getParameters(), Procedure.CallingConvention.STACK_CALL, call.getSource(), hasParamOrReturn?call.getComments():Comment.NO_COMMENTS)); + stmtIt.add(new StatementCallExecute(procedureType, call.getProcedure(), Procedure.CallingConvention.STACK_CALL, call.getSource(), hasParamOrReturn?Comment.NO_COMMENTS:call.getComments())); + stmtIt.add(new StatementCallFinalize(call.getlValue(), procedureType, null, Procedure.CallingConvention.STACK_CALL, call.getSource(), Comment.NO_COMMENTS)); + getLog().append("Calling convention " + Procedure.CallingConvention.STACK_CALL + " adding prepare/execute/finalize for " + call.toString(getProgram(), false)); + //} } + } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java index 96b2f1cd9..4383dd96e 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java @@ -13,6 +13,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeStruct; import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.passes.unwinding.ValueSource; import dk.camelot64.kickc.passes.unwinding.ValueSourceFactory; +import dk.camelot64.kickc.passes.unwinding.ValueSourceParamValue; import java.util.ArrayList; import java.util.List; @@ -281,6 +282,8 @@ public class Pass1UnwindStructValues extends Pass1Base { public static boolean copyValues(ValueSource lValueSource, ValueSource rValueSource, List lValueUnwoundList, boolean initialAssignment, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt, Program program) { if(lValueSource == null || rValueSource == null) return false; + if(rValueSource instanceof ValueSourceParamValue && lValueSource.equals(((ValueSourceParamValue) rValueSource).getValueSource())) + return false; if(lValueSource.equals(rValueSource)) return true; if(lValueSource.isSimple() && rValueSource.isSimple()) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertBlocks.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertBlocks.java index bd7589a4e..a26f6a2ca 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertBlocks.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertBlocks.java @@ -88,8 +88,10 @@ public class Pass2AssertBlocks extends Pass2SsaAssertion { @Override public Void visitCallExecute(StatementCallExecute callExecute) { ProcedureRef procedure = callExecute.getProcedure(); - LabelRef procLabelRef = procedure.getLabelRef(); - assertBlock(procLabelRef); + if(procedure!=null) { + LabelRef procLabelRef = procedure.getLabelRef(); + assertBlock(procLabelRef); + } return super.visitCallExecute(callExecute); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantCallPointerIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantCallPointerIdentification.java index 8e2861f17..ff75592af 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantCallPointerIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantCallPointerIdentification.java @@ -3,8 +3,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementCall; -import dk.camelot64.kickc.model.statements.StatementCallPointer; +import dk.camelot64.kickc.model.statements.StatementCallExecute; import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; @@ -28,14 +27,14 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization ListIterator statementsIt = block.getStatements().listIterator(); while(statementsIt.hasNext()) { Statement statement = statementsIt.next(); - if(statement instanceof StatementCallPointer) { - StatementCallPointer callPointer = (StatementCallPointer) statement; - RValue procedure = callPointer.getProcedure(); + if(statement instanceof StatementCallExecute) { + StatementCallExecute callPointer = (StatementCallExecute) statement; + RValue procedure = callPointer.getProcedureRVal(); if(procedure instanceof PointerDereferenceSimple) { RValue pointer = ((PointerDereferenceSimple) procedure).getPointer(); ProcedureRef constProcedureRef = findConstProcedure(pointer); if(constProcedureRef != null) { - replacePointerCall(callPointer, constProcedureRef, statementsIt, block); + replacePointerCall(callPointer, constProcedureRef, block); optimized = true; } } else if(procedure instanceof ConstantRef) { @@ -45,7 +44,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) { ProcedureRef constProcedureRef = findConstProcedure(procedure); if(constProcedureRef != null) { - replacePointerCall(callPointer, constProcedureRef, statementsIt, block); + replacePointerCall(callPointer, constProcedureRef, block); optimized = true; } } @@ -59,21 +58,16 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization /** * Replace a pointer-based call to a constant procedure with a classic procedure call - * @param callPointer The call to replace + * @param callPointer The call to replace * @param constProcedureRef The constant procedure pointed to - * @param statementsIt The statement iterator currently pointing to the pointer-based call * @param block The block containing the call */ - private void replacePointerCall(StatementCallPointer callPointer, ProcedureRef constProcedureRef, ListIterator statementsIt, ControlFlowBlock block) { - statementsIt.remove(); - StatementCall call = new StatementCall(callPointer.getlValue(), constProcedureRef.getFullName(), callPointer.getParameters(), callPointer.getSource(), callPointer.getComments()); - call.setProcedure(constProcedureRef); - call.setIndex(callPointer.getIndex()); + private void replacePointerCall(StatementCallExecute callPointer, ProcedureRef constProcedureRef, ControlFlowBlock block) { + callPointer.setProcedure(constProcedureRef); block.setCallSuccessor(constProcedureRef.getLabelRef()); - statementsIt.add(call); final Procedure procedure = getScope().getProcedure(constProcedureRef); procedure.setCallingConvention(Procedure.CallingConvention.STACK_CALL); - getLog().append("Replacing constant pointer function " + call.toString(getProgram(), false)); + getLog().append("Replacing constant pointer function " + callPointer.toString(getProgram(), false)); } /** diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java index 6fa70537a..bf98717b2 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java @@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValue; import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.operators.OperatorBinary; import dk.camelot64.kickc.model.operators.OperatorUnary; @@ -140,7 +141,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { if(var.isVolatile() || var.isKindLoadStore()) // Do not examine volatiles and non-versioned variables continue; - if(var.getRegister()!=null && var.getRegister().isMem()) + if(var.getRegister() != null && var.getRegister().isMem()) // Skip variables allocated into memory continue; ConstantValue constant = getConstant(assignment.getrValue2()); @@ -173,7 +174,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { if(variable.isVolatile() || !variable.isKindLoadStore()) // Do not examine volatiles, non-constants or versioned variables continue; - if(variable.getRegister()!=null && variable.getRegister().isMem()) + if(variable.getRegister() != null && variable.getRegister().isMem()) // Skip variables allocated into memory continue; final List varAssignments = VarAssignments.get(variable.getRef(), getGraph(), getScope()); @@ -290,7 +291,8 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { ProgramValueIterator.execute(program, (programValue, currentStmt, stmtIt, currentBlock) -> { Value value = programValue.get(); if(value instanceof ProcedureRef && value.equals(procedureRef)) { - found[0] = true; + if(!(programValue instanceof ProgramValue.CallExecuteProcedure)) + found[0] = true; } }); if(found[0]) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateUnusedBlocks.java b/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateUnusedBlocks.java index 38959ee86..e7df46537 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateUnusedBlocks.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateUnusedBlocks.java @@ -77,6 +77,7 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization { /** * Removes an entire procedure from the program (control flow graph and symbol table) + * * @param procedureRef The procedure to remove * @param removedBlocks A set where all removed blocks are added to. */ @@ -173,7 +174,9 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization { findReferencedBlocks(getGraph().getBlock(procedure.getLabelRef()), used); } else if(statement instanceof StatementCallExecute) { final ProcedureRef procedure = ((StatementCallExecute) statement).getProcedure(); - findReferencedBlocks(getGraph().getBlock(procedure.getLabelRef()), used); + if(procedure != null) { + findReferencedBlocks(getGraph().getBlock(procedure.getLabelRef()), used); + } } } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 49f6562f3..898b9fddb 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -811,11 +811,15 @@ public class Pass4CodeGeneration { try { generateStatementAsm(asm, block, statement, aluState, true); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { + StatementSource statementSource = statement.getSource(); if(warnFragmentMissing) { - program.getLog().append("Warning! Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature() + "\n" + statement.getSource().format()); + String stmtFormat = ""; + if(statementSource!=null) + stmtFormat = statementSource.format(); + program.getLog().append("Warning! Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature() + "\n" + stmtFormat); asm.addLine(new AsmInlineKickAsm(".assert \"Missing ASM fragment " + e.getFragmentSignature() + "\", 0, 1", 0L, 0L)); } else { - throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statement.getSource()); + throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statementSource); } } catch(CompileError e) { if(e.getSource() == null) { @@ -909,8 +913,55 @@ public class Pass4CodeGeneration { } } else if(statement instanceof StatementCallExecute) { StatementCallExecute call = (StatementCallExecute) statement; - asm.getCurrentChunk().setFragment("jsr"); - asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false); + RValue procedureRVal = call.getProcedureRVal(); + boolean supported = false; + if(procedureRVal instanceof ProcedureRef) { + asm.getCurrentChunk().setFragment("jsr"); + asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false); + supported = true; + } else if(procedureRVal instanceof PointerDereferenceSimple) { + RValue pointer = ((PointerDereferenceSimple) procedureRVal).getPointer(); + if(pointer instanceof ConstantValue) { + ensureEncoding(asm, pointer); + asm.addInstruction("jsr", CpuAddressingMode.ABS, AsmFormat.getAsmConstant(program, (ConstantValue) pointer, 99, block.getScope()), false); + asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); + supported = true; + } else if(pointer instanceof VariableRef) { + Variable variable = getScope().getVariable((VariableRef) pointer); + generateIndirectCall(asm, variable, block.getScope()); + asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); + supported = true; + } else if(pointer instanceof CastValue && ((CastValue) pointer).getValue() instanceof VariableRef) { + Variable variable = getScope().getVariable((VariableRef) ((CastValue) pointer).getValue()); + generateIndirectCall(asm, variable, block.getScope()); + asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); + supported = true; + } + } else if(procedureRVal instanceof VariableRef) { + Variable procedureVariable = getScope().getVariable((VariableRef) procedureRVal); + SymbolType procedureVariableType = procedureVariable.getType(); + if(procedureVariableType instanceof SymbolTypePointer) { + if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) { + generateIndirectCall(asm, procedureVariable, block.getScope()); + supported = true; + asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); + } + } + } else if(procedureRVal instanceof ConstantRef) { + Variable procedureVariable = getScope().getConstant((ConstantRef) procedureRVal); + SymbolType procedureVariableType = procedureVariable.getType(); + if(procedureVariableType instanceof SymbolTypePointer) { + if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) { + String varAsmName = AsmFormat.getAsmSymbolName(program, procedureVariable, block.getScope()); + asm.addInstruction("jsr", CpuAddressingMode.ABS, varAsmName, false); + asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); + supported = true; + } + } + } + if(!supported) { + throw new InternalError("Call Pointer not supported " + statement); + } } else if(statement instanceof StatementExprSideEffect) { AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program); ensureEncoding(asm, asmFragmentInstanceSpecBuilder); @@ -952,51 +1003,6 @@ public class Pass4CodeGeneration { asm.getCurrentChunk().setClobberOverwrite(statementKasm.getDeclaredClobber()); } } else if(statement instanceof StatementCallPointer) { - StatementCallPointer callPointer = (StatementCallPointer) statement; - RValue procedure = callPointer.getProcedure(); - boolean supported = false; - if(procedure instanceof PointerDereferenceSimple) { - RValue pointer = ((PointerDereferenceSimple) procedure).getPointer(); - if(pointer instanceof ConstantValue) { - ensureEncoding(asm, pointer); - asm.addInstruction("jsr", CpuAddressingMode.ABS, AsmFormat.getAsmConstant(program, (ConstantValue) pointer, 99, block.getScope()), false); - supported = true; - } else if(pointer instanceof VariableRef) { - Variable variable = getScope().getVariable((VariableRef) pointer); - generateIndirectCall(asm, variable, block.getScope()); - supported = true; - } else if(pointer instanceof CastValue && ((CastValue) pointer).getValue() instanceof VariableRef) { - Variable variable = getScope().getVariable((VariableRef) ((CastValue) pointer).getValue()); - generateIndirectCall(asm, variable, block.getScope()); - supported = true; - } - } else if(procedure instanceof VariableRef) { - Variable procedureVariable = getScope().getVariable((VariableRef) procedure); - SymbolType procedureVariableType = procedureVariable.getType(); - if(procedureVariableType instanceof SymbolTypePointer) { - if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) { - generateIndirectCall(asm, procedureVariable, block.getScope()); - supported = true; - } - } - } else if(procedure instanceof ConstantRef) { - Variable procedureVariable = getScope().getConstant((ConstantRef) procedure); - SymbolType procedureVariableType = procedureVariable.getType(); - if(procedureVariableType instanceof SymbolTypePointer) { - if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) { - String varAsmName = AsmFormat.getAsmSymbolName(program, procedureVariable, block.getScope()); - asm.addInstruction("jsr", CpuAddressingMode.ABS, varAsmName, false); - supported = true; - } - } - } - if(supported) { - asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); - } - if(!supported) { - throw new InternalError("Call Pointer not supported " + statement); - } - } else { throw new InternalError("Statement not supported " + statement); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java b/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java index f8cb34d54..ae2b2215d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java @@ -81,10 +81,12 @@ public class Pass4InterruptClobberFix extends Pass2Base { List calls = callBlock.getCalls(); for(CallGraph.CallBlock.Call call : calls) { ScopeRef calledProcLabel = call.getProcedure(); - ProcedureRef calledProcRef = new ProcedureRef(calledProcLabel.getFullName()); - Procedure calledProc = getProgram().getScope().getProcedure(calledProcRef); - CpuClobber calledClobber = getProcedureClobber(calledProc); - procClobber = new CpuClobber(procClobber, calledClobber); + if(calledProcLabel!=null) { + ProcedureRef calledProcRef = new ProcedureRef(calledProcLabel.getFullName()); + Procedure calledProc = getProgram().getScope().getProcedure(calledProcRef); + CpuClobber calledClobber = getProcedureClobber(calledProc); + procClobber = new CpuClobber(procClobber, calledClobber); + } } return procClobber; diff --git a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcBlockSuccessorClosure.java b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcBlockSuccessorClosure.java index 5f0432181..be90d5fb4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcBlockSuccessorClosure.java +++ b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcBlockSuccessorClosure.java @@ -54,7 +54,8 @@ public class PassNCalcBlockSuccessorClosure extends PassNCalcBase procReferenced = procedureReferencedVars.get(procedure); - // The call statement has no used or defined by itself so only work with the alive vars - for(VariableRef aliveVar : aliveNextStmt) { - // Add all variables to previous that are not used inside the method - if(!procReferenced.contains(aliveVar) && !definedNextStmt.contains(aliveVar)) { - boolean added = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx()); - modified |= added; - if(added && getLog().isVerboseLiveRanges()) { - getLog().append("Propagated alive var unused in method by skipping call " + aliveVar + " to " + previousStmt.getStatement()); + if(procedure!=null) { + Collection procReferenced = procedureReferencedVars.get(procedure); + // The call statement has no used or defined by itself so only work with the alive vars + for(VariableRef aliveVar : aliveNextStmt) { + // Add all variables to previous that are not used inside the method + if(!procReferenced.contains(aliveVar) && !definedNextStmt.contains(aliveVar)) { + boolean added = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx()); + modified |= added; + if(added && getLog().isVerboseLiveRanges()) { + getLog().append("Propagated alive var unused in method by skipping call " + aliveVar + " to " + previousStmt.getStatement()); + } } } } @@ -256,12 +258,14 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase lastStatements = getLastInBlock(returnBlock, getGraph()); - for(Statement lastStatement : lastStatements) { - previousStatements.add(new PreviousStatement(lastStatement, PreviousStatement.Type.LAST_IN_METHOD)); + if(procedure!=null) { + LabelRef procedureReturnBlock = procedure.getReturnBlock(); + ControlFlowBlock returnBlock = getProgram().getGraph().getBlock(procedureReturnBlock); + if(returnBlock != null) { + Collection lastStatements = getLastInBlock(returnBlock, getGraph()); + for(Statement lastStatement : lastStatements) { + previousStatements.add(new PreviousStatement(lastStatement, PreviousStatement.Type.LAST_IN_METHOD)); + } } } } else if(precedingStatements.size() > 0) { diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceParamValue.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceParamValue.java index 9dff01e65..509dbe4ba 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceParamValue.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceParamValue.java @@ -23,6 +23,10 @@ public class ValueSourceParamValue extends ValueSourceBase { this.valueSource = valueSource; } + public ValueSource getValueSource() { + return valueSource; + } + @Override public SymbolType getSymbolType() { return valueSource.getSymbolType(); diff --git a/src/test/java/dk/camelot64/kickc/test/TestProgramsFast.java b/src/test/java/dk/camelot64/kickc/test/TestProgramsFast.java index ee21713a5..9f9d5f504 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestProgramsFast.java +++ b/src/test/java/dk/camelot64/kickc/test/TestProgramsFast.java @@ -3176,10 +3176,10 @@ public class TestProgramsFast extends TestPrograms { compileAndCompare("function-pointer-param-workaround.c"); } - //@Test - //public void testFunctionPointerParam0() throws IOException { - // compileAndCompare("function-pointer-param-0.c", log().verboseParse().verboseCreateSsa()); - //} + @Test + public void testFunctionPointerParam0() throws IOException { + compileAndCompare("function-pointer-param-0.c"); + } @Test public void testFunctionPointerNoargCall14() throws IOException { @@ -3252,7 +3252,12 @@ public class TestProgramsFast extends TestPrograms { } @Test - public void testFunctionPointerReturn() throws IOException { + public void testFunctionPointerReturn1() throws IOException { + compileAndCompare("function-pointer-return-1.c"); + } + + @Test + public void testFunctionPointerReturn0() throws IOException { compileAndCompare("function-pointer-return.c"); } diff --git a/src/test/kc/function-pointer-return-1.c b/src/test/kc/function-pointer-return-1.c new file mode 100644 index 000000000..bfd12bb4d --- /dev/null +++ b/src/test/kc/function-pointer-return-1.c @@ -0,0 +1,31 @@ +// Tests calling functions pointer with no parameter and a return value + +void main() { + char* const SCREEN = (char*)0x400; + + char(*f)(); + + char i = 0; + for(;;) { + ++i; + if((i&1)==0) { + f = &fn1; + } else { + f = &fn2; + } + char v = (*f)(); + SCREEN[0] = v; + } +} + +char fn1() { + char* const BORDER_COLOR = (char*)0xd020; + (*BORDER_COLOR)++; + return *BORDER_COLOR; +} + +char fn2() { + char* const BG_COLOR = (char*)0xd021; + (*BG_COLOR)++; + return *BG_COLOR; +} \ No newline at end of file diff --git a/src/test/kc/procedure-callingconvention-stack-10.c b/src/test/kc/procedure-callingconvention-stack-10.c index b3b0339f7..884584778 100644 --- a/src/test/kc/procedure-callingconvention-stack-10.c +++ b/src/test/kc/procedure-callingconvention-stack-10.c @@ -2,6 +2,7 @@ // Returning and passing struct values #pragma calling(__stackcall) +#pragma struct_model(classic) char* const SCREEN = (char*)0x0400; char idx = 0; diff --git a/src/test/kc/procedure-callingconvention-stack-11.c b/src/test/kc/procedure-callingconvention-stack-11.c index 2c4c9047d..aa0563bde 100644 --- a/src/test/kc/procedure-callingconvention-stack-11.c +++ b/src/test/kc/procedure-callingconvention-stack-11.c @@ -2,6 +2,7 @@ // Returning and passing struct of struct values #pragma calling(__stackcall) +#pragma struct_model(classic) char* const SCREEN = (char*)0x0400; char idx = 0; diff --git a/src/test/ref/examples/c64/music/music.cfg b/src/test/ref/examples/c64/music/music.cfg index 6e51cd7fb..c0e4908a7 100644 --- a/src/test/ref/examples/c64/music/music.cfg +++ b/src/test/ref/examples/c64/music/music.cfg @@ -1,13 +1,14 @@ void main() main: scope:[main] from - [0] call *musicInit + [0] phi() + [1] callexecute *musicInit to:main::@1 main::@1: scope:[main] from main main::@1 main::@2 - [1] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 + [2] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 to:main::@2 main::@2: scope:[main] from main::@1 - [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) - [3] call *musicPlay - [4] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) + [3] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) + [4] callexecute *musicPlay + [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:main::@1 diff --git a/src/test/ref/examples/c64/music/music.log b/src/test/ref/examples/c64/music/music.log index e33dce236..0218cb17d 100644 --- a/src/test/ref/examples/c64/music/music.log +++ b/src/test/ref/examples/c64/music/music.log @@ -1,11 +1,13 @@ Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *musicInit +Calling convention STACK_CALL adding prepare/execute/finalize for call *musicPlay CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start::@1 - call *musicInit + callexecute *musicInit to:main::@1 main::@1: scope:[main] from main main::@1 main::@2 main::$1 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) != $fd @@ -13,7 +15,7 @@ main::@1: scope:[main] from main main::@1 main::@2 to:main::@2 main::@2: scope:[main] from main::@1 *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) - call *musicPlay + callexecute *musicPlay *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) if(true) goto main::@1 to:main::@return @@ -73,24 +75,28 @@ Removing unused procedure block __start::@return Successful SSA optimization PassNEliminateEmptyStart Finalized unsigned number type (word) $1000 Successful SSA optimization PassNFinalizeNumberTypeConversions +Adding NOP phi() at start of main CALL GRAPH +Calls in [main] to null:1 null:4 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes +Adding NOP phi() at start of main FINAL CONTROL FLOW GRAPH void main() main: scope:[main] from - [0] call *musicInit + [0] phi() + [1] callexecute *musicInit to:main::@1 main::@1: scope:[main] from main main::@1 main::@2 - [1] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 + [2] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 to:main::@2 main::@2: scope:[main] from main::@1 - [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) - [3] call *musicPlay - [4] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) + [3] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) + [4] callexecute *musicPlay + [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:main::@1 @@ -100,9 +106,9 @@ void main() Initial phi equivalence classes Complete equivalence classes REGISTER UPLIFT POTENTIAL REGISTERS -Statement [0] call *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y -Statement [1] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [3] call *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [1] callexecute *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [2] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [4] callexecute *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y REGISTER UPLIFT SCOPES Uplift Scope [MOS6526_CIA] @@ -148,26 +154,26 @@ ASSEMBLER BEFORE OPTIMIZATION // main // Play the music main: { - // [0] call *musicInit + // [1] callexecute *musicInit // Initialize the music jsr musicInit jmp __b1 // Wait for the RASTER // main::@1 __b1: - // [1] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 -- _deref_pbuc1_neq_vbuc2_then_la1 + // [2] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 -- _deref_pbuc1_neq_vbuc2_then_la1 lda #$fd cmp VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER bne __b1 jmp __b2 // main::@2 __b2: - // [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_inc__deref_pbuc1 + // [3] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_inc__deref_pbuc1 inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR - // [3] call *musicPlay + // [4] callexecute *musicPlay // Play the music jsr musicPlay - // [4] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 + // [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR jmp __b1 } @@ -234,27 +240,27 @@ Score: 1066 // Play the music main: { // (*musicInit)() - // [0] call *musicInit + // [1] callexecute *musicInit // Initialize the music jsr musicInit // Wait for the RASTER // main::@1 __b1: // while (VICII->RASTER != $fd) - // [1] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 -- _deref_pbuc1_neq_vbuc2_then_la1 + // [2] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)!=$fd) goto main::@1 -- _deref_pbuc1_neq_vbuc2_then_la1 lda #$fd cmp VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER bne __b1 // main::@2 // (VICII->BORDER_COLOR)++; - // [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_inc__deref_pbuc1 + // [3] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_inc__deref_pbuc1 inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR // (*musicPlay)() - // [3] call *musicPlay + // [4] callexecute *musicPlay // Play the music jsr musicPlay // (VICII->BORDER_COLOR)--; - // [4] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 + // [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR jmp __b1 } diff --git a/src/test/ref/examples/c64/music/music_irq.cfg b/src/test/ref/examples/c64/music/music_irq.cfg index c98528365..112c18478 100644 --- a/src/test/ref/examples/c64/music/music_irq.cfg +++ b/src/test/ref/examples/c64/music/music_irq.cfg @@ -2,7 +2,7 @@ __interrupt(rom_sys_c64) void irq_play() irq_play: scope:[irq_play] from [0] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) - [1] call *musicPlay + [1] callexecute *musicPlay [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [3] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:irq_play::@return @@ -13,7 +13,7 @@ irq_play::@return: scope:[irq_play] from irq_play void main() main: scope:[main] from asm { sei } - [6] call *musicInit + [6] callexecute *musicInit [7] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [9] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $fd diff --git a/src/test/ref/examples/c64/music/music_irq.log b/src/test/ref/examples/c64/music/music_irq.log index f39865f95..b36c8f8b2 100644 --- a/src/test/ref/examples/c64/music/music_irq.log +++ b/src/test/ref/examples/c64/music/music_irq.log @@ -1,13 +1,15 @@ Resolved forward reference irq_play to __interrupt(rom_sys_c64) void irq_play() Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *musicInit +Calling convention STACK_CALL adding prepare/execute/finalize for call *musicPlay CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start::@1 asm { sei } - call *musicInit + callexecute *musicInit *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $fd @@ -22,7 +24,7 @@ main::@return: scope:[main] from main __interrupt(rom_sys_c64) void irq_play() irq_play: scope:[irq_play] from *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) - call *musicPlay + callexecute *musicPlay *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:irq_play::@return @@ -92,6 +94,8 @@ Successful SSA optimization PassNEliminateEmptyStart Finalized unsigned number type (word) $1000 Successful SSA optimization PassNFinalizeNumberTypeConversions CALL GRAPH +Calls in [irq_play] to null:1 +Calls in [main] to null:6 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes @@ -101,7 +105,7 @@ FINAL CONTROL FLOW GRAPH __interrupt(rom_sys_c64) void irq_play() irq_play: scope:[irq_play] from [0] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) - [1] call *musicPlay + [1] callexecute *musicPlay [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [3] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:irq_play::@return @@ -112,7 +116,7 @@ irq_play::@return: scope:[irq_play] from irq_play void main() main: scope:[main] from asm { sei } - [6] call *musicInit + [6] callexecute *musicInit [7] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [9] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $fd @@ -132,9 +136,9 @@ void main() Initial phi equivalence classes Complete equivalence classes REGISTER UPLIFT POTENTIAL REGISTERS -Statement [1] call *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [1] callexecute *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y Statement [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a -Statement [6] call *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [6] callexecute *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y Statement [7] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( [ ] { } ) always clobbers reg byte a Statement [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( [ ] { } ) always clobbers reg byte a Statement [9] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $fd [ ] ( [ ] { } ) always clobbers reg byte a @@ -208,7 +212,7 @@ irq_play: { // interrupt(isr_rom_sys_c64_entry) -- isr_rom_sys_c64_entry // [0] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_inc__deref_pbuc1 inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR - // [1] call *musicPlay + // [1] callexecute *musicPlay // Play SID jsr musicPlay // [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER -- _deref_pbuc1=vbuc2 @@ -229,7 +233,7 @@ irq_play: { main: { // asm { sei } sei - // [6] call *musicInit + // [6] callexecute *musicInit jsr musicInit // [7] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 // Disable CIA 1 Timer IRQ @@ -356,7 +360,7 @@ irq_play: { // [0] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = ++ *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_inc__deref_pbuc1 inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR // (*musicPlay)() - // [1] call *musicPlay + // [1] callexecute *musicPlay // Play SID jsr musicPlay // VICII->IRQ_STATUS = IRQ_RASTER @@ -380,7 +384,7 @@ main: { // asm { sei } sei // (*musicInit)() - // [6] call *musicInit + // [6] callexecute *musicInit jsr musicInit // CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR // [7] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/examples/mega65/banked-music.cfg b/src/test/ref/examples/mega65/banked-music.cfg index 300e0c306..c80dcf0ee 100644 --- a/src/test/ref/examples/mega65/banked-music.cfg +++ b/src/test/ref/examples/mega65/banked-music.cfg @@ -6,113 +6,114 @@ irq: scope:[irq] from [2] call memoryRemapBlock to:irq::@3 irq::@3: scope:[irq] from irq - [3] call *musicPlay - [4] call memoryRemap + [3] phi() + [4] callexecute *musicPlay + [5] call memoryRemap to:irq::@4 irq::@4: scope:[irq] from irq::@3 - [5] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) + [6] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) to:irq::@1 irq::@1: scope:[irq] from irq::@1 irq::@4 - [6] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 + [7] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 to:irq::@2 irq::@2: scope:[irq] from irq::@1 - [7] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) + [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:irq::@return irq::@return: scope:[irq] from irq::@2 - [8] return + [9] return to:@return void main() main: scope:[main] from asm { sei } - [10] call memoryRemap + [11] call memoryRemap to:main::@4 main::@4: scope:[main] from main - [11] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 - [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 - [13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 - [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 - [15] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK - [16] *PROCPORT = PROCPORT_RAM_IO - [17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 - [18] call memcpy_dma4 + [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 + [13] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 + [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 + [15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 + [16] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK + [17] *PROCPORT = PROCPORT_RAM_IO + [18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 + [19] call memcpy_dma4 to:main::@5 main::@5: scope:[main] from main::@4 - [19] phi() - [20] call memoryRemapBlock + [20] phi() + [21] call memoryRemapBlock to:main::@6 main::@6: scope:[main] from main::@5 asm { lda#0 } - [22] call *musicInit - [23] call memoryRemap + [23] callexecute *musicInit + [24] call memoryRemap to:main::@7 main::@7: scope:[main] from main::@6 - [24] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR - [25] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff - [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f - [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER - [28] *HARDWARE_IRQ = &irq + [25] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR + [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff + [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f + [28] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER + [29] *HARDWARE_IRQ = &irq asm { cli } to:main::@1 main::@1: scope:[main] from main::@2 main::@7 - [30] main::mem_destroy_i#2 = phi( main::@2/main::mem_destroy_i#1, main::@7/0 ) - [31] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] - [32] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 + [31] main::mem_destroy_i#2 = phi( main::@2/main::mem_destroy_i#1, main::@7/0 ) + [32] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] + [33] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 to:main::@2 main::@2: scope:[main] from main::@1 main::@3 - [33] main::i#2 = phi( main::@1/0, main::@3/main::i#1 ) - [34] if(main::i#2<$f0) goto main::@3 + [34] main::i#2 = phi( main::@1/0, main::@3/main::i#1 ) + [35] if(main::i#2<$f0) goto main::@3 to:main::@1 main::@3: scope:[main] from main::@2 - [35] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] - [36] main::i#1 = ++ main::i#2 + [36] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] + [37] main::i#1 = ++ main::i#2 to:main::@2 void memoryRemapBlock(byte memoryRemapBlock::blockPage , word memoryRemapBlock::memoryPage) memoryRemapBlock: scope:[memoryRemapBlock] from irq main::@5 - [37] phi() - [38] call memoryRemap + [38] phi() + [39] call memoryRemap to:memoryRemapBlock::@return memoryRemapBlock::@return: scope:[memoryRemapBlock] from memoryRemapBlock - [39] return + [40] return to:@return void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset) memoryRemap: scope:[memoryRemap] from irq::@3 main main::@6 memoryRemapBlock - [40] memoryRemap::upperPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) - [40] memoryRemap::remapBlocks#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::blockBits#0 ) - [40] memoryRemap::lowerPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) - [41] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 - [42] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 - [43] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 - [44] memoryRemap::$3 = memoryRemap::$2 & $f - [45] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 - [46] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 - [47] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 - [48] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 - [49] memoryRemap::$8 = memoryRemap::$7 & $f - [50] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 + [41] memoryRemap::upperPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) + [41] memoryRemap::remapBlocks#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::blockBits#0 ) + [41] memoryRemap::lowerPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) + [42] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 + [43] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 + [44] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 + [45] memoryRemap::$3 = memoryRemap::$2 & $f + [46] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 + [47] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 + [48] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 + [49] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 + [50] memoryRemap::$8 = memoryRemap::$7 & $f + [51] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } to:memoryRemap::@return memoryRemap::@return: scope:[memoryRemap] from memoryRemap - [52] return + [53] return to:@return void memcpy_dma4(byte memcpy_dma4::dest_bank , void* memcpy_dma4::dest , byte memcpy_dma4::src_bank , void* memcpy_dma4::src , word memcpy_dma4::num) memcpy_dma4: scope:[memcpy_dma4] from main::@4 - [53] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) - [54] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 - [55] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 - [56] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 - [57] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 - [58] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 - [59] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 - [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 - [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 - [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 - [63] *((byte*)DMA) = byte0 &memcpy_dma_command4 - [64] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memcpy_dma4::dmaMode#0 + [54] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) + [55] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 + [56] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 + [57] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 + [58] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 + [59] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 + [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 + [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 + [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 + [63] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 + [64] *((byte*)DMA) = byte0 &memcpy_dma_command4 + [65] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memcpy_dma4::dmaMode#0 to:memcpy_dma4::@return memcpy_dma4::@return: scope:[memcpy_dma4] from memcpy_dma4 - [65] return + [66] return to:@return diff --git a/src/test/ref/examples/mega65/banked-music.log b/src/test/ref/examples/mega65/banked-music.log index 12deb3a59..cc791792b 100644 --- a/src/test/ref/examples/mega65/banked-music.log +++ b/src/test/ref/examples/mega65/banked-music.log @@ -62,6 +62,8 @@ Eliminating unused variable with no statement memoryRemapBlock::$1 Eliminating unused variable with no statement memoryRemapBlock::$2 Eliminating unused variable with no statement memcpy_dma_command Eliminating unused variable with no statement memset_dma_command +Calling convention STACK_CALL adding prepare/execute/finalize for call *musicInit +Calling convention STACK_CALL adding prepare/execute/finalize for call *musicPlay CONTROL FLOW GRAPH SSA @@ -159,7 +161,7 @@ main::@5: scope:[main] from main::@4 to:main::@6 main::@6: scope:[main] from main::@5 asm { lda#0 } - call *musicInit + callexecute *musicInit memoryRemap::remapBlocks#2 = 0 memoryRemap::lowerPageOffset#2 = 0 memoryRemap::upperPageOffset#2 = 0 @@ -205,7 +207,7 @@ irq: scope:[irq] from call memoryRemapBlock to:irq::@3 irq::@3: scope:[irq] from irq - call *musicPlay + callexecute *musicPlay memoryRemap::remapBlocks#3 = 0 memoryRemap::lowerPageOffset#3 = 0 memoryRemap::upperPageOffset#3 = 0 @@ -631,20 +633,22 @@ Finalized unsigned number type (byte) 0 Finalized unsigned number type (word) $4000 Successful SSA optimization PassNFinalizeNumberTypeConversions Added new block during phi lifting main::@8(between main::@2 and main::@1) +Adding NOP phi() at start of irq::@3 Adding NOP phi() at start of main::@5 Adding NOP phi() at start of memoryRemapBlock Adding NOP phi() at start of memoryRemapBlock::@1 CALL GRAPH -Calls in [irq] to memoryRemapBlock:2 memoryRemap:4 -Calls in [main] to memoryRemap:10 memcpy_dma4:18 memoryRemapBlock:20 memoryRemap:23 -Calls in [memoryRemapBlock] to memoryRemap:40 +Calls in [irq] to memoryRemapBlock:2 null:4 memoryRemap:5 +Calls in [main] to memoryRemap:11 memcpy_dma4:19 memoryRemapBlock:21 null:23 memoryRemap:24 +Calls in [memoryRemapBlock] to memoryRemap:41 Created 5 initial phi equivalence classes -Coalesced [35] main::mem_destroy_i#5 = main::mem_destroy_i#1 -Coalesced [38] main::i#4 = main::i#1 +Coalesced [36] main::mem_destroy_i#5 = main::mem_destroy_i#1 +Coalesced [39] main::i#4 = main::i#1 Coalesced down to 5 phi equivalence classes Culled Empty Block label main::@8 Culled Empty Block label memoryRemapBlock::@1 +Adding NOP phi() at start of irq::@3 Adding NOP phi() at start of main::@5 Adding NOP phi() at start of memoryRemapBlock @@ -657,115 +661,116 @@ irq: scope:[irq] from [2] call memoryRemapBlock to:irq::@3 irq::@3: scope:[irq] from irq - [3] call *musicPlay - [4] call memoryRemap + [3] phi() + [4] callexecute *musicPlay + [5] call memoryRemap to:irq::@4 irq::@4: scope:[irq] from irq::@3 - [5] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) + [6] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) to:irq::@1 irq::@1: scope:[irq] from irq::@1 irq::@4 - [6] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 + [7] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 to:irq::@2 irq::@2: scope:[irq] from irq::@1 - [7] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) + [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) to:irq::@return irq::@return: scope:[irq] from irq::@2 - [8] return + [9] return to:@return void main() main: scope:[main] from asm { sei } - [10] call memoryRemap + [11] call memoryRemap to:main::@4 main::@4: scope:[main] from main - [11] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 - [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 - [13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 - [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 - [15] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK - [16] *PROCPORT = PROCPORT_RAM_IO - [17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 - [18] call memcpy_dma4 + [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 + [13] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 + [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 + [15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 + [16] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK + [17] *PROCPORT = PROCPORT_RAM_IO + [18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 + [19] call memcpy_dma4 to:main::@5 main::@5: scope:[main] from main::@4 - [19] phi() - [20] call memoryRemapBlock + [20] phi() + [21] call memoryRemapBlock to:main::@6 main::@6: scope:[main] from main::@5 asm { lda#0 } - [22] call *musicInit - [23] call memoryRemap + [23] callexecute *musicInit + [24] call memoryRemap to:main::@7 main::@7: scope:[main] from main::@6 - [24] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR - [25] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff - [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f - [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER - [28] *HARDWARE_IRQ = &irq + [25] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR + [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff + [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f + [28] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER + [29] *HARDWARE_IRQ = &irq asm { cli } to:main::@1 main::@1: scope:[main] from main::@2 main::@7 - [30] main::mem_destroy_i#2 = phi( main::@2/main::mem_destroy_i#1, main::@7/0 ) - [31] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] - [32] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 + [31] main::mem_destroy_i#2 = phi( main::@2/main::mem_destroy_i#1, main::@7/0 ) + [32] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] + [33] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 to:main::@2 main::@2: scope:[main] from main::@1 main::@3 - [33] main::i#2 = phi( main::@1/0, main::@3/main::i#1 ) - [34] if(main::i#2<$f0) goto main::@3 + [34] main::i#2 = phi( main::@1/0, main::@3/main::i#1 ) + [35] if(main::i#2<$f0) goto main::@3 to:main::@1 main::@3: scope:[main] from main::@2 - [35] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] - [36] main::i#1 = ++ main::i#2 + [36] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] + [37] main::i#1 = ++ main::i#2 to:main::@2 void memoryRemapBlock(byte memoryRemapBlock::blockPage , word memoryRemapBlock::memoryPage) memoryRemapBlock: scope:[memoryRemapBlock] from irq main::@5 - [37] phi() - [38] call memoryRemap + [38] phi() + [39] call memoryRemap to:memoryRemapBlock::@return memoryRemapBlock::@return: scope:[memoryRemapBlock] from memoryRemapBlock - [39] return + [40] return to:@return void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset) memoryRemap: scope:[memoryRemap] from irq::@3 main main::@6 memoryRemapBlock - [40] memoryRemap::upperPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) - [40] memoryRemap::remapBlocks#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::blockBits#0 ) - [40] memoryRemap::lowerPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) - [41] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 - [42] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 - [43] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 - [44] memoryRemap::$3 = memoryRemap::$2 & $f - [45] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 - [46] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 - [47] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 - [48] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 - [49] memoryRemap::$8 = memoryRemap::$7 & $f - [50] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 + [41] memoryRemap::upperPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) + [41] memoryRemap::remapBlocks#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::blockBits#0 ) + [41] memoryRemap::lowerPageOffset#4 = phi( irq::@3/0, main/0, main::@6/0, memoryRemapBlock/memoryRemapBlock::pageOffset#0 ) + [42] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 + [43] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 + [44] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 + [45] memoryRemap::$3 = memoryRemap::$2 & $f + [46] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 + [47] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 + [48] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 + [49] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 + [50] memoryRemap::$8 = memoryRemap::$7 & $f + [51] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } to:memoryRemap::@return memoryRemap::@return: scope:[memoryRemap] from memoryRemap - [52] return + [53] return to:@return void memcpy_dma4(byte memcpy_dma4::dest_bank , void* memcpy_dma4::dest , byte memcpy_dma4::src_bank , void* memcpy_dma4::src , word memcpy_dma4::num) memcpy_dma4: scope:[memcpy_dma4] from main::@4 - [53] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) - [54] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 - [55] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 - [56] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 - [57] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 - [58] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 - [59] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 - [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 - [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 - [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 - [63] *((byte*)DMA) = byte0 &memcpy_dma_command4 - [64] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memcpy_dma4::dmaMode#0 + [54] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) + [55] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 + [56] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 + [57] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 + [58] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 + [59] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 + [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 + [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 + [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 + [63] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 + [64] *((byte*)DMA) = byte0 &memcpy_dma_command4 + [65] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memcpy_dma4::dmaMode#0 to:memcpy_dma4::@return memcpy_dma4::@return: scope:[memcpy_dma4] from memcpy_dma4 - [65] return + [66] return to:@return @@ -871,81 +876,81 @@ Allocated zp[1]:20 [ memcpy_dma4::dmaMode#0 ] Allocated mem[12] [ memcpy_dma_command4 ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a -Statement [3] call *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [8] return [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [11] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [15] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [16] *PROCPORT = PROCPORT_RAM_IO [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [4] callexecute *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [9] return [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [13] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [16] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [17] *PROCPORT = PROCPORT_RAM_IO [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a Statement asm { lda#0 } always clobbers reg byte a -Statement [22] call *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [24] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( [ ] { } ) always clobbers reg byte a -Statement [25] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff [ ] ( [ ] { } ) always clobbers reg byte a -Statement [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( [ ] { } ) always clobbers reg byte a -Statement [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a -Statement [28] *HARDWARE_IRQ = &irq [ ] ( [ ] { } ) always clobbers reg byte a -Statement [35] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] [ main::mem_destroy_i#1 main::i#2 ] ( [ main::mem_destroy_i#1 main::i#2 ] { } ) always clobbers reg byte a +Statement [23] callexecute *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [25] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( [ ] { } ) always clobbers reg byte a +Statement [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff [ ] ( [ ] { } ) always clobbers reg byte a +Statement [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( [ ] { } ) always clobbers reg byte a +Statement [28] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a +Statement [29] *HARDWARE_IRQ = &irq [ ] ( [ ] { } ) always clobbers reg byte a +Statement [36] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] [ main::mem_destroy_i#1 main::i#2 ] ( [ main::mem_destroy_i#1 main::i#2 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::mem_destroy_i#2 main::mem_destroy_i#1 ] Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#2 main::i#1 ] -Statement [41] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] ( memoryRemap:4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:23 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } ) always clobbers reg byte a +Statement [42] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] ( memoryRemap:5 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:24 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:6 [ memoryRemap::remapBlocks#4 ] -Statement [42] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] ( memoryRemap:4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:23 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } ) always clobbers reg byte a -Statement [44] memoryRemap::$3 = memoryRemap::$2 & $f [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] ( memoryRemap:4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:23 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } ) always clobbers reg byte a +Statement [43] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] ( memoryRemap:5 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:24 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } ) always clobbers reg byte a +Statement [45] memoryRemap::$3 = memoryRemap::$2 & $f [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] ( memoryRemap:5 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:24 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:11 [ memoryRemap::$1 ] -Statement [46] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] ( memoryRemap:4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:23 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } ) always clobbers reg byte a -Statement [47] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] ( memoryRemap:4 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:23 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } ) always clobbers reg byte a -Statement [49] memoryRemap::$8 = memoryRemap::$7 & $f [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] ( memoryRemap:4 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:23 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } ) always clobbers reg byte a +Statement [47] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] ( memoryRemap:5 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:24 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } ) always clobbers reg byte a +Statement [48] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] ( memoryRemap:5 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:24 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } ) always clobbers reg byte a +Statement [50] memoryRemap::$8 = memoryRemap::$7 & $f [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] ( memoryRemap:5 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:24 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:16 [ memoryRemap::$6 ] Statement asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [54] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [55] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:20 [ memcpy_dma4::dmaMode#0 ] -Statement [55] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [56] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [57] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [58] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [59] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [63] *((byte*)DMA) = byte0 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 ] { } ) always clobbers reg byte a +Statement [56] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [57] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [58] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [59] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [63] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [64] *((byte*)DMA) = byte0 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 ] { } ) always clobbers reg byte a Statement [0] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a -Statement [3] call *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [8] return [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [11] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [15] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [16] *PROCPORT = PROCPORT_RAM_IO [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [4] callexecute *musicPlay [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [9] return [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [13] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [16] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [17] *PROCPORT = PROCPORT_RAM_IO [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ memcpy_dma_command4 ] ( [ memcpy_dma_command4 ] { } ) always clobbers reg byte a Statement asm { lda#0 } always clobbers reg byte a -Statement [22] call *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [24] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( [ ] { } ) always clobbers reg byte a -Statement [25] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff [ ] ( [ ] { } ) always clobbers reg byte a -Statement [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( [ ] { } ) always clobbers reg byte a -Statement [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a -Statement [28] *HARDWARE_IRQ = &irq [ ] ( [ ] { } ) always clobbers reg byte a -Statement [35] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] [ main::mem_destroy_i#1 main::i#2 ] ( [ main::mem_destroy_i#1 main::i#2 ] { } ) always clobbers reg byte a -Statement [41] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] ( memoryRemap:4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:23 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } ) always clobbers reg byte a -Statement [42] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] ( memoryRemap:4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:23 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } ) always clobbers reg byte a -Statement [44] memoryRemap::$3 = memoryRemap::$2 & $f [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] ( memoryRemap:4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:23 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } ) always clobbers reg byte a -Statement [46] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] ( memoryRemap:4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:23 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } ) always clobbers reg byte a -Statement [47] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] ( memoryRemap:4 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:23 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } ) always clobbers reg byte a -Statement [49] memoryRemap::$8 = memoryRemap::$7 & $f [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] ( memoryRemap:4 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:10 [ memcpy_dma_command4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:23 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:2::memoryRemap:38 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:20::memoryRemap:38 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } ) always clobbers reg byte a +Statement [23] callexecute *musicInit [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [25] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( [ ] { } ) always clobbers reg byte a +Statement [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff [ ] ( [ ] { } ) always clobbers reg byte a +Statement [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( [ ] { } ) always clobbers reg byte a +Statement [28] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a +Statement [29] *HARDWARE_IRQ = &irq [ ] ( [ ] { } ) always clobbers reg byte a +Statement [36] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] [ main::mem_destroy_i#1 main::i#2 ] ( [ main::mem_destroy_i#1 main::i#2 ] { } ) always clobbers reg byte a +Statement [42] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] ( memoryRemap:5 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemap:24 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal ] { } ) always clobbers reg byte a +Statement [43] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] ( memoryRemap:5 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemap:24 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::lowerPageOffset#4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 ] { } ) always clobbers reg byte a +Statement [45] memoryRemap::$3 = memoryRemap::$2 & $f [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] ( memoryRemap:5 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemap:24 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::$1 memoryRemap::$3 ] { } ) always clobbers reg byte a +Statement [47] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] ( memoryRemap:5 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemap:24 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::remapBlocks#4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal ] { } ) always clobbers reg byte a +Statement [48] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] ( memoryRemap:5 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemap:24 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::upperPageOffset#4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 ] { } ) always clobbers reg byte a +Statement [50] memoryRemap::$8 = memoryRemap::$7 & $f [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] ( memoryRemap:5 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:11 [ memcpy_dma_command4 memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemap:24 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:2::memoryRemap:39 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } memoryRemapBlock:21::memoryRemap:39 [ memoryRemap::aVal memoryRemap::xVal memoryRemap::yVal memoryRemap::$6 memoryRemap::$8 ] { } ) always clobbers reg byte a Statement asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [54] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [55] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [56] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [57] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [58] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [59] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a -Statement [63] *((byte*)DMA) = byte0 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 ] ( memcpy_dma4:18 [ memcpy_dma4::dmaMode#0 ] { } ) always clobbers reg byte a +Statement [55] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [56] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [57] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [58] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [59] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [63] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 memcpy_dma_command4 ] { } ) always clobbers reg byte a +Statement [64] *((byte*)DMA) = byte0 &memcpy_dma_command4 [ memcpy_dma4::dmaMode#0 ] ( memcpy_dma4:19 [ memcpy_dma4::dmaMode#0 ] { } ) always clobbers reg byte a Potential registers zp[1]:2 [ main::mem_destroy_i#2 main::mem_destroy_i#1 ] : zp[1]:2 , reg byte x , reg byte y , reg byte z , Potential registers zp[1]:3 [ main::i#2 main::i#1 ] : zp[1]:3 , reg byte x , reg byte y , reg byte z , Potential registers zp[2]:4 [ memoryRemap::lowerPageOffset#4 ] : zp[2]:4 , @@ -1120,27 +1125,29 @@ irq: { inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR // [2] call memoryRemapBlock // Remap memory to put music at $4000 - // [37] phi from irq to memoryRemapBlock [phi:irq->memoryRemapBlock] + // [38] phi from irq to memoryRemapBlock [phi:irq->memoryRemapBlock] memoryRemapBlock_from_irq: jsr memoryRemapBlock + // [3] phi from irq to irq::@3 [phi:irq->irq::@3] + __b3_from_irq: jmp __b3 // irq::@3 __b3: - // [3] call *musicPlay + // [4] callexecute *musicPlay // Play remapped SID jsr musicPlay - // [4] call memoryRemap + // [5] call memoryRemap // Reset memory mapping - // [40] phi from irq::@3 to memoryRemap [phi:irq::@3->memoryRemap] + // [41] phi from irq::@3 to memoryRemap [phi:irq::@3->memoryRemap] memoryRemap_from___b3: - // [40] phi memoryRemap::upperPageOffset#4 = 0 [phi:irq::@3->memoryRemap#0] -- vwuz1=vbuc1 + // [41] phi memoryRemap::upperPageOffset#4 = 0 [phi:irq::@3->memoryRemap#0] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.upperPageOffset lda #>0 sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = 0 [phi:irq::@3->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = 0 [phi:irq::@3->memoryRemap#1] -- vbuzz=vbuc1 ldz #0 - // [40] phi memoryRemap::lowerPageOffset#4 = 0 [phi:irq::@3->memoryRemap#2] -- vwuz1=vbuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = 0 [phi:irq::@3->memoryRemap#2] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.lowerPageOffset lda #>0 @@ -1149,24 +1156,24 @@ irq: { jmp __b4 // irq::@4 __b4: - // [5] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 + // [6] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 // Wait for the next raster line lda VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER jmp __b1 // irq::@1 __b1: - // [6] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 -- _deref_pbuc1_eq_vbuaa_then_la1 + // [7] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 -- _deref_pbuc1_eq_vbuaa_then_la1 cmp VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER beq __b1 jmp __b2 // irq::@2 __b2: - // [7] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 + // [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR jmp __breturn // irq::@return __breturn: - // [8] return + // [9] return // interrupt(isr_hardware_clobber_exit) -- isr_hardware_all_exit plz ply @@ -1179,18 +1186,18 @@ main: { // asm { sei } // Stop IRQ's sei - // [10] call memoryRemap + // [11] call memoryRemap // Map memory to BANK 0 : 0x00XXXX - giving access to I/O - // [40] phi from main to memoryRemap [phi:main->memoryRemap] + // [41] phi from main to memoryRemap [phi:main->memoryRemap] memoryRemap_from_main: - // [40] phi memoryRemap::upperPageOffset#4 = 0 [phi:main->memoryRemap#0] -- vwuz1=vbuc1 + // [41] phi memoryRemap::upperPageOffset#4 = 0 [phi:main->memoryRemap#0] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.upperPageOffset lda #>0 sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = 0 [phi:main->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = 0 [phi:main->memoryRemap#1] -- vbuzz=vbuc1 ldz #0 - // [40] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main->memoryRemap#2] -- vwuz1=vbuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main->memoryRemap#2] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.lowerPageOffset lda #>0 @@ -1199,44 +1206,44 @@ main: { jmp __b4 // main::@4 __b4: - // [11] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 + // [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 // Enable MEGA65 features lda #$47 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY - // [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 + // [13] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 lda #$53 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY - // [13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Enable 48MHz fast mode lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB - // [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC - // [15] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 + // [16] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 // no kernal or BASIC rom visible lda #PROCPORT_DDR_MEMORY_MASK sta PROCPORT_DDR - // [16] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 + // [17] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 lda #PROCPORT_RAM_IO sta PROCPORT - // [17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 + // [18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 // open sideborder lda #1 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO - // [18] call memcpy_dma4 + // [19] call memcpy_dma4 // Transfer banked code/data to upper memory ($10000) jsr memcpy_dma4 - // [19] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + // [20] phi from main::@4 to main::@5 [phi:main::@4->main::@5] __b5_from___b4: jmp __b5 // main::@5 __b5: - // [20] call memoryRemapBlock + // [21] call memoryRemapBlock // Remap [$4000-$5fff] to point to [$10000-$11fff] - // [37] phi from main::@5 to memoryRemapBlock [phi:main::@5->memoryRemapBlock] + // [38] phi from main::@5 to memoryRemapBlock [phi:main::@5->memoryRemapBlock] memoryRemapBlock_from___b5: jsr memoryRemapBlock jmp __b6 @@ -1245,20 +1252,20 @@ main: { // asm { lda#0 } // Initialize SID lda #0 - // [22] call *musicInit + // [23] callexecute *musicInit jsr musicInit - // [23] call memoryRemap + // [24] call memoryRemap // Reset memory mapping - // [40] phi from main::@6 to memoryRemap [phi:main::@6->memoryRemap] + // [41] phi from main::@6 to memoryRemap [phi:main::@6->memoryRemap] memoryRemap_from___b6: - // [40] phi memoryRemap::upperPageOffset#4 = 0 [phi:main::@6->memoryRemap#0] -- vwuz1=vbuc1 + // [41] phi memoryRemap::upperPageOffset#4 = 0 [phi:main::@6->memoryRemap#0] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.upperPageOffset lda #>0 sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = 0 [phi:main::@6->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = 0 [phi:main::@6->memoryRemap#1] -- vbuzz=vbuc1 ldz #0 - // [40] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main::@6->memoryRemap#2] -- vwuz1=vbuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main::@6->memoryRemap#2] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.lowerPageOffset lda #>0 @@ -1267,24 +1274,24 @@ main: { jmp __b7 // main::@7 __b7: - // [24] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 + // [25] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 // Set up raster interrupts C64 style // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT - // [25] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff -- _deref_pbuc1=vbuc2 + // [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff -- _deref_pbuc1=vbuc2 // Set raster line to 0xff lda #$ff sta VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER - // [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 lda #$7f and VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 - // [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 + // [28] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE - // [28] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 + // [29] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 // Set the IRQ routine lda #main::@1] + // [31] phi from main::@7 to main::@1 [phi:main::@7->main::@1] __b1_from___b7: - // [30] phi main::mem_destroy_i#2 = 0 [phi:main::@7->main::@1#0] -- vbuxx=vbuc1 + // [31] phi main::mem_destroy_i#2 = 0 [phi:main::@7->main::@1#0] -- vbuxx=vbuc1 ldx #0 jmp __b1 // main::@1 __b1: - // [31] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx + // [32] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx inc MUSIC,x - // [32] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 -- vbuxx=_inc_vbuxx + // [33] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 -- vbuxx=_inc_vbuxx inx - // [33] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + // [34] phi from main::@1 to main::@2 [phi:main::@1->main::@2] __b2_from___b1: - // [33] phi main::i#2 = 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1 + // [34] phi main::i#2 = 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1 ldy #0 jmp __b2 // Show unmapped MUSIC memory // main::@2 __b2: - // [34] if(main::i#2<$f0) goto main::@3 -- vbuyy_lt_vbuc1_then_la1 + // [35] if(main::i#2<$f0) goto main::@3 -- vbuyy_lt_vbuc1_then_la1 cpy #$f0 bcc __b3 - // [30] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [31] phi from main::@2 to main::@1 [phi:main::@2->main::@1] __b1_from___b2: - // [30] phi main::mem_destroy_i#2 = main::mem_destroy_i#1 [phi:main::@2->main::@1#0] -- register_copy + // [31] phi main::mem_destroy_i#2 = main::mem_destroy_i#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 // main::@3 __b3: - // [35] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuyy + // [36] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuyy lda MUSIC,y sta DEFAULT_SCREEN,y - // [36] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy + // [37] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy iny - // [33] phi from main::@3 to main::@2 [phi:main::@3->main::@2] + // [34] phi from main::@3 to main::@2 [phi:main::@3->main::@2] __b2_from___b3: - // [33] phi main::i#2 = main::i#1 [phi:main::@3->main::@2#0] -- register_copy + // [34] phi main::i#2 = main::i#1 [phi:main::@3->main::@2#0] -- register_copy jmp __b2 } // memoryRemapBlock @@ -1343,17 +1350,17 @@ memoryRemapBlock: { // Which block is being remapped? (0-7) .const block = $40>>5 .const blockBits = 1<memoryRemap] + // [39] call memoryRemap + // [41] phi from memoryRemapBlock to memoryRemap [phi:memoryRemapBlock->memoryRemap] memoryRemap_from_memoryRemapBlock: - // [40] phi memoryRemap::upperPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#0] -- vwuz1=vwuc1 + // [41] phi memoryRemap::upperPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#0] -- vwuz1=vwuc1 lda #pageOffset sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = memoryRemapBlock::blockBits#0 [phi:memoryRemapBlock->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = memoryRemapBlock::blockBits#0 [phi:memoryRemapBlock->memoryRemap#1] -- vbuzz=vbuc1 ldz #blockBits - // [40] phi memoryRemap::lowerPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#2] -- vwuz1=vwuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#2] -- vwuz1=vwuc1 lda #pageOffset @@ -1362,7 +1369,7 @@ memoryRemapBlock: { jmp __breturn // memoryRemapBlock::@return __breturn: - // [39] return + // [40] return rts } // memoryRemap @@ -1400,38 +1407,38 @@ memoryRemap: { .label __6 = $a .label lowerPageOffset = 2 .label upperPageOffset = 4 - // [41] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 -- vbuz1=_byte0_vwuz2 + // [42] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 -- vbuz1=_byte0_vwuz2 // lower blocks offset page low lda.z lowerPageOffset sta.z aVal - // [42] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 -- vbuz1=vbuzz_rol_4 + // [43] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 -- vbuz1=vbuzz_rol_4 tza asl asl asl asl sta.z __1 - // [43] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 -- vbuaa=_byte1_vwuz1 + // [44] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 -- vbuaa=_byte1_vwuz1 lda.z lowerPageOffset+1 - // [44] memoryRemap::$3 = memoryRemap::$2 & $f -- vbuaa=vbuaa_band_vbuc1 + // [45] memoryRemap::$3 = memoryRemap::$2 & $f -- vbuaa=vbuaa_band_vbuc1 and #$f - // [45] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 -- vbuz1=vbuz2_bor_vbuaa + // [46] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 -- vbuz1=vbuz2_bor_vbuaa // lower blocks to map + lower blocks offset high nibble ora.z __1 sta.z xVal - // [46] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 -- vbuz1=_byte0_vwuz2 + // [47] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 -- vbuz1=_byte0_vwuz2 // upper blocks offset page lda.z upperPageOffset sta.z yVal - // [47] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 -- vbuz1=vbuzz_band_vbuc1 + // [48] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 -- vbuz1=vbuzz_band_vbuc1 tza and #$f0 sta.z __6 - // [48] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 -- vbuaa=_byte1_vwuz1 + // [49] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 -- vbuaa=_byte1_vwuz1 lda.z upperPageOffset+1 - // [49] memoryRemap::$8 = memoryRemap::$7 & $f -- vbuaa=vbuaa_band_vbuc1 + // [50] memoryRemap::$8 = memoryRemap::$7 & $f -- vbuaa=vbuaa_band_vbuc1 and #$f - // [50] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 -- vbuz1=vbuz2_bor_vbuaa + // [51] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 -- vbuz1=vbuz2_bor_vbuaa // upper blocks to map + upper blocks offset page high nibble ora.z __6 sta.z zVal @@ -1445,7 +1452,7 @@ memoryRemap: { jmp __breturn // memoryRemap::@return __breturn: - // [52] return + // [53] return rts } // memcpy_dma4 @@ -1462,56 +1469,56 @@ memcpy_dma4: { .const src_bank = 0 .label dest = 0 .label src = upperCodeData - // [53] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1 + // [54] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1 // Remember current F018 A/B mode ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B - // [54] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 -- _deref_pwuc1=vwuc2 + // [55] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 -- _deref_pwuc1=vwuc2 // Set up command lda #num sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1 - // [55] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 -- _deref_pbuc1=vbuc2 + // [56] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 -- _deref_pbuc1=vbuc2 lda #src_bank sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK - // [56] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 -- _deref_qbuc1=pbuc2 + // [57] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 -- _deref_qbuc1=pbuc2 lda #src sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1 - // [57] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 -- _deref_pbuc1=vbuc2 + // [58] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 -- _deref_pbuc1=vbuc2 lda #dest_bank sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK - // [58] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 -- _deref_qbuc1=pbuc2 + // [59] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 -- _deref_qbuc1=pbuc2 lda #dest sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1 - // [59] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2 + // [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2 // Set F018B mode lda #1 sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B - // [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2 + // [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2 // Set address of DMA list lda #0 sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB - // [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2 + // [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2 lda #0 sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK - // [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 + // [63] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 lda #>memcpy_dma_command4 sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB - // [63] *((byte*)DMA) = byte0 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 + // [64] *((byte*)DMA) = byte0 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 // Trigger the DMA (without option lists) lda #0 Removing instruction lda #0 Succesful ASM optimization Pass5UnnecesaryLoadElimination +Removing instruction __b3_from_irq: Removing instruction __b5_from___b4: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction memoryRemapBlock_from_irq: @@ -1803,45 +1811,46 @@ irq: { // memoryRemapBlock(0x40, 0x100) // [2] call memoryRemapBlock // Remap memory to put music at $4000 - // [37] phi from irq to memoryRemapBlock [phi:irq->memoryRemapBlock] + // [38] phi from irq to memoryRemapBlock [phi:irq->memoryRemapBlock] jsr memoryRemapBlock + // [3] phi from irq to irq::@3 [phi:irq->irq::@3] // irq::@3 // (*musicPlay)() - // [3] call *musicPlay + // [4] callexecute *musicPlay // Play remapped SID jsr musicPlay // memoryRemap(0,0,0) - // [4] call memoryRemap + // [5] call memoryRemap // Reset memory mapping - // [40] phi from irq::@3 to memoryRemap [phi:irq::@3->memoryRemap] - // [40] phi memoryRemap::upperPageOffset#4 = 0 [phi:irq::@3->memoryRemap#0] -- vwuz1=vbuc1 + // [41] phi from irq::@3 to memoryRemap [phi:irq::@3->memoryRemap] + // [41] phi memoryRemap::upperPageOffset#4 = 0 [phi:irq::@3->memoryRemap#0] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.upperPageOffset sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = 0 [phi:irq::@3->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = 0 [phi:irq::@3->memoryRemap#1] -- vbuzz=vbuc1 ldz #0 - // [40] phi memoryRemap::lowerPageOffset#4 = 0 [phi:irq::@3->memoryRemap#2] -- vwuz1=vbuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = 0 [phi:irq::@3->memoryRemap#2] -- vwuz1=vbuc1 sta.z memoryRemap.lowerPageOffset sta.z memoryRemap.lowerPageOffset+1 jsr memoryRemap // irq::@4 // char raster = VICII->RASTER - // [5] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 + // [6] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 // Wait for the next raster line lda VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER // irq::@1 __b1: // while(VICII->RASTER==raster) - // [6] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 -- _deref_pbuc1_eq_vbuaa_then_la1 + // [7] if(*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)==irq::raster#0) goto irq::@1 -- _deref_pbuc1_eq_vbuaa_then_la1 cmp VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER beq __b1 // irq::@2 // (VICII->BORDER_COLOR)--; - // [7] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 + // [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = -- *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) -- _deref_pbuc1=_dec__deref_pbuc1 dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR // irq::@return // } - // [8] return + // [9] return // interrupt(isr_hardware_clobber_exit) -- isr_hardware_all_exit plz ply @@ -1856,64 +1865,64 @@ main: { // Stop IRQ's sei // memoryRemap(0,0,0) - // [10] call memoryRemap + // [11] call memoryRemap // Map memory to BANK 0 : 0x00XXXX - giving access to I/O - // [40] phi from main to memoryRemap [phi:main->memoryRemap] - // [40] phi memoryRemap::upperPageOffset#4 = 0 [phi:main->memoryRemap#0] -- vwuz1=vbuc1 + // [41] phi from main to memoryRemap [phi:main->memoryRemap] + // [41] phi memoryRemap::upperPageOffset#4 = 0 [phi:main->memoryRemap#0] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.upperPageOffset sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = 0 [phi:main->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = 0 [phi:main->memoryRemap#1] -- vbuzz=vbuc1 ldz #0 - // [40] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main->memoryRemap#2] -- vwuz1=vbuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main->memoryRemap#2] -- vwuz1=vbuc1 sta.z memoryRemap.lowerPageOffset sta.z memoryRemap.lowerPageOffset+1 jsr memoryRemap // main::@4 // VICIII->KEY = 0x47 - // [11] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 + // [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 // Enable MEGA65 features lda #$47 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY // VICIII->KEY = 0x53 - // [12] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 + // [13] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 lda #$53 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY // VICIV->CONTROLB |= 0x40 - // [13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Enable 48MHz fast mode lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB // VICIV->CONTROLC |= 0x40 - // [14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC // *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK - // [15] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 + // [16] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 // no kernal or BASIC rom visible lda #PROCPORT_DDR_MEMORY_MASK sta PROCPORT_DDR // *PROCPORT = PROCPORT_RAM_IO - // [16] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 + // [17] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 lda #PROCPORT_RAM_IO sta PROCPORT // VICIV->SIDBDRWD_LO = 1 - // [17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 + // [18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 // open sideborder lda #1 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO // memcpy_dma4(1, (void*)0x0000, 0, upperCodeData, MUSIC_END-MUSIC) - // [18] call memcpy_dma4 + // [19] call memcpy_dma4 // Transfer banked code/data to upper memory ($10000) jsr memcpy_dma4 - // [19] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + // [20] phi from main::@4 to main::@5 [phi:main::@4->main::@5] // main::@5 // memoryRemapBlock(0x40, 0x100) - // [20] call memoryRemapBlock + // [21] call memoryRemapBlock // Remap [$4000-$5fff] to point to [$10000-$11fff] - // [37] phi from main::@5 to memoryRemapBlock [phi:main::@5->memoryRemapBlock] + // [38] phi from main::@5 to memoryRemapBlock [phi:main::@5->memoryRemapBlock] jsr memoryRemapBlock // main::@6 // asm @@ -1921,46 +1930,46 @@ main: { // Initialize SID lda #0 // (*musicInit)() - // [22] call *musicInit + // [23] callexecute *musicInit jsr musicInit // memoryRemap(0,0,0) - // [23] call memoryRemap + // [24] call memoryRemap // Reset memory mapping - // [40] phi from main::@6 to memoryRemap [phi:main::@6->memoryRemap] - // [40] phi memoryRemap::upperPageOffset#4 = 0 [phi:main::@6->memoryRemap#0] -- vwuz1=vbuc1 + // [41] phi from main::@6 to memoryRemap [phi:main::@6->memoryRemap] + // [41] phi memoryRemap::upperPageOffset#4 = 0 [phi:main::@6->memoryRemap#0] -- vwuz1=vbuc1 lda #<0 sta.z memoryRemap.upperPageOffset sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = 0 [phi:main::@6->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = 0 [phi:main::@6->memoryRemap#1] -- vbuzz=vbuc1 ldz #0 - // [40] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main::@6->memoryRemap#2] -- vwuz1=vbuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = 0 [phi:main::@6->memoryRemap#2] -- vwuz1=vbuc1 sta.z memoryRemap.lowerPageOffset sta.z memoryRemap.lowerPageOffset+1 jsr memoryRemap // main::@7 // CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR - // [24] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 + // [25] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 // Set up raster interrupts C64 style // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT // VICII->RASTER = 0xff - // [25] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff -- _deref_pbuc1=vbuc2 + // [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = $ff -- _deref_pbuc1=vbuc2 // Set raster line to 0xff lda #$ff sta VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER // VICII->CONTROL1 &= 0x7f - // [26] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 lda #$7f and VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 // VICII->IRQ_ENABLE = IRQ_RASTER - // [27] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 + // [28] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE // *HARDWARE_IRQ = &irq - // [28] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 + // [29] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 // Set the IRQ routine lda #main::@1] - // [30] phi main::mem_destroy_i#2 = 0 [phi:main::@7->main::@1#0] -- vbuxx=vbuc1 + // [31] phi from main::@7 to main::@1 [phi:main::@7->main::@1] + // [31] phi main::mem_destroy_i#2 = 0 [phi:main::@7->main::@1#0] -- vbuxx=vbuc1 ldx #0 // main::@1 __b1: // MUSIC[mem_destroy_i++]++; - // [31] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx + // [32] MUSIC[main::mem_destroy_i#2] = ++ MUSIC[main::mem_destroy_i#2] -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx inc MUSIC,x - // [32] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 -- vbuxx=_inc_vbuxx + // [33] main::mem_destroy_i#1 = ++ main::mem_destroy_i#2 -- vbuxx=_inc_vbuxx inx - // [33] phi from main::@1 to main::@2 [phi:main::@1->main::@2] - // [33] phi main::i#2 = 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1 + // [34] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + // [34] phi main::i#2 = 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1 ldy #0 // Show unmapped MUSIC memory // main::@2 __b2: // for(char i=0;i<240;i++) - // [34] if(main::i#2<$f0) goto main::@3 -- vbuyy_lt_vbuc1_then_la1 + // [35] if(main::i#2<$f0) goto main::@3 -- vbuyy_lt_vbuc1_then_la1 cpy #$f0 bcc __b3 - // [30] phi from main::@2 to main::@1 [phi:main::@2->main::@1] - // [30] phi main::mem_destroy_i#2 = main::mem_destroy_i#1 [phi:main::@2->main::@1#0] -- register_copy + // [31] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [31] phi main::mem_destroy_i#2 = main::mem_destroy_i#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 // main::@3 __b3: // DEFAULT_SCREEN[i] = MUSIC[i] - // [35] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuyy + // [36] DEFAULT_SCREEN[main::i#2] = MUSIC[main::i#2] -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuyy lda MUSIC,y sta DEFAULT_SCREEN,y // for(char i=0;i<240;i++) - // [36] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy + // [37] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy iny - // [33] phi from main::@3 to main::@2 [phi:main::@3->main::@2] - // [33] phi main::i#2 = main::i#1 [phi:main::@3->main::@2#0] -- register_copy + // [34] phi from main::@3 to main::@2 [phi:main::@3->main::@2] + // [34] phi main::i#2 = main::i#1 [phi:main::@3->main::@2#0] -- register_copy jmp __b2 } // memoryRemapBlock @@ -2019,16 +2028,16 @@ memoryRemapBlock: { .const block = $40>>5 .const blockBits = 1<memoryRemap] - // [40] phi memoryRemap::upperPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#0] -- vwuz1=vwuc1 + // [39] call memoryRemap + // [41] phi from memoryRemapBlock to memoryRemap [phi:memoryRemapBlock->memoryRemap] + // [41] phi memoryRemap::upperPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#0] -- vwuz1=vwuc1 lda #pageOffset sta.z memoryRemap.upperPageOffset+1 - // [40] phi memoryRemap::remapBlocks#4 = memoryRemapBlock::blockBits#0 [phi:memoryRemapBlock->memoryRemap#1] -- vbuzz=vbuc1 + // [41] phi memoryRemap::remapBlocks#4 = memoryRemapBlock::blockBits#0 [phi:memoryRemapBlock->memoryRemap#1] -- vbuzz=vbuc1 ldz #blockBits - // [40] phi memoryRemap::lowerPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#2] -- vwuz1=vwuc1 + // [41] phi memoryRemap::lowerPageOffset#4 = memoryRemapBlock::pageOffset#0 [phi:memoryRemapBlock->memoryRemap#2] -- vwuz1=vwuc1 lda #pageOffset @@ -2036,7 +2045,7 @@ memoryRemapBlock: { jsr memoryRemap // memoryRemapBlock::@return // } - // [39] return + // [40] return rts } // memoryRemap @@ -2075,12 +2084,12 @@ memoryRemap: { .label lowerPageOffset = 2 .label upperPageOffset = 4 // char aVal = BYTE0(lowerPageOffset) - // [41] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 -- vbuz1=_byte0_vwuz2 + // [42] memoryRemap::aVal = byte0 memoryRemap::lowerPageOffset#4 -- vbuz1=_byte0_vwuz2 // lower blocks offset page low lda.z lowerPageOffset sta.z aVal // remapBlocks << 4 - // [42] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 -- vbuz1=vbuzz_rol_4 + // [43] memoryRemap::$1 = memoryRemap::remapBlocks#4 << 4 -- vbuz1=vbuzz_rol_4 tza asl asl @@ -2088,34 +2097,34 @@ memoryRemap: { asl sta.z __1 // BYTE1(lowerPageOffset) - // [43] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 -- vbuaa=_byte1_vwuz1 + // [44] memoryRemap::$2 = byte1 memoryRemap::lowerPageOffset#4 -- vbuaa=_byte1_vwuz1 lda.z lowerPageOffset+1 // BYTE1(lowerPageOffset) & 0xf - // [44] memoryRemap::$3 = memoryRemap::$2 & $f -- vbuaa=vbuaa_band_vbuc1 + // [45] memoryRemap::$3 = memoryRemap::$2 & $f -- vbuaa=vbuaa_band_vbuc1 and #$f // char xVal = (remapBlocks << 4) | (BYTE1(lowerPageOffset) & 0xf) - // [45] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 -- vbuz1=vbuz2_bor_vbuaa + // [46] memoryRemap::xVal = memoryRemap::$1 | memoryRemap::$3 -- vbuz1=vbuz2_bor_vbuaa // lower blocks to map + lower blocks offset high nibble ora.z __1 sta.z xVal // char yVal = BYTE0(upperPageOffset) - // [46] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 -- vbuz1=_byte0_vwuz2 + // [47] memoryRemap::yVal = byte0 memoryRemap::upperPageOffset#4 -- vbuz1=_byte0_vwuz2 // upper blocks offset page lda.z upperPageOffset sta.z yVal // remapBlocks & 0xf0 - // [47] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 -- vbuz1=vbuzz_band_vbuc1 + // [48] memoryRemap::$6 = memoryRemap::remapBlocks#4 & $f0 -- vbuz1=vbuzz_band_vbuc1 tza and #$f0 sta.z __6 // BYTE1(upperPageOffset) - // [48] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 -- vbuaa=_byte1_vwuz1 + // [49] memoryRemap::$7 = byte1 memoryRemap::upperPageOffset#4 -- vbuaa=_byte1_vwuz1 lda.z upperPageOffset+1 // BYTE1(upperPageOffset) & 0xf - // [49] memoryRemap::$8 = memoryRemap::$7 & $f -- vbuaa=vbuaa_band_vbuc1 + // [50] memoryRemap::$8 = memoryRemap::$7 & $f -- vbuaa=vbuaa_band_vbuc1 and #$f // char zVal = (remapBlocks & 0xf0) | (BYTE1(upperPageOffset) & 0xf) - // [50] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 -- vbuz1=vbuz2_bor_vbuaa + // [51] memoryRemap::zVal = memoryRemap::$6 | memoryRemap::$8 -- vbuz1=vbuz2_bor_vbuaa // upper blocks to map + upper blocks offset page high nibble ora.z __6 sta.z zVal @@ -2129,7 +2138,7 @@ memoryRemap: { eom // memoryRemap::@return // } - // [52] return + // [53] return rts } // memcpy_dma4 @@ -2147,65 +2156,65 @@ memcpy_dma4: { .label dest = 0 .label src = upperCodeData // char dmaMode = DMA->EN018B - // [53] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1 + // [54] memcpy_dma4::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1 // Remember current F018 A/B mode ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B // memcpy_dma_command4.count = num - // [54] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 -- _deref_pwuc1=vwuc2 + // [55] *((word*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memcpy_dma4::num#0 -- _deref_pwuc1=vwuc2 // Set up command lda #num sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1 // memcpy_dma_command4.src_bank = src_bank - // [55] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 -- _deref_pbuc1=vbuc2 + // [56] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK) = memcpy_dma4::src_bank#0 -- _deref_pbuc1=vbuc2 lda #src_bank sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC_BANK // memcpy_dma_command4.src = src - // [56] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 -- _deref_qbuc1=pbuc2 + // [57] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memcpy_dma4::src#0 -- _deref_qbuc1=pbuc2 lda #src sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1 // memcpy_dma_command4.dest_bank = dest_bank - // [57] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 -- _deref_pbuc1=vbuc2 + // [58] *((byte*)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memcpy_dma4::dest_bank#0 -- _deref_pbuc1=vbuc2 lda #dest_bank sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK // memcpy_dma_command4.dest = dest - // [58] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 -- _deref_qbuc1=pbuc2 + // [59] *((byte**)&memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memcpy_dma4::dest#0 -- _deref_qbuc1=pbuc2 lda #dest sta memcpy_dma_command4+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1 // DMA->EN018B = 1 - // [59] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2 + // [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2 // Set F018B mode lda #1 sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B // DMA->ADDRMB = 0 - // [60] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2 + // [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2 // Set address of DMA list lda #0 sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB // DMA->ADDRBANK = 0 - // [61] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2 + // [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2 sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK // DMA-> ADDRMSB = BYTE1(&memcpy_dma_command4) - // [62] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 + // [63] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = byte1 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 lda #>memcpy_dma_command4 sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB // DMA-> ADDRLSBTRIG = BYTE0(&memcpy_dma_command4) - // [63] *((byte*)DMA) = byte0 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 + // [64] *((byte*)DMA) = byte0 &memcpy_dma_command4 -- _deref_pbuc1=vbuc2 // Trigger the DMA (without option lists) lda #EN018B = dmaMode - // [64] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memcpy_dma4::dmaMode#0 -- _deref_pbuc1=vbuxx + // [65] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memcpy_dma4::dmaMode#0 -- _deref_pbuc1=vbuxx // Re-enable F018A mode stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B // memcpy_dma4::@return // } - // [65] return + // [66] return rts } // File Data diff --git a/src/test/ref/examples/mega65/raster65.cfg b/src/test/ref/examples/mega65/raster65.cfg index a0c4f4c80..599174a7a 100644 --- a/src/test/ref/examples/mega65/raster65.cfg +++ b/src/test/ref/examples/mega65/raster65.cfg @@ -32,247 +32,248 @@ irq::@1: scope:[irq] from irq irq::@9 [15] if(irq::line#10!=RASTER_LINES) goto irq::@2 to:irq::@3 irq::@3: scope:[irq] from irq::@1 - [16] call *songPlay - [17] irq::sin_col#0 = sin_idx + [16] phi() + [17] callexecute *songPlay + [18] irq::sin_col#0 = sin_idx to:irq::@16 irq::@16: scope:[irq] from irq::@17 irq::@3 - [18] irq::sin_col#2 = phi( irq::@17/irq::sin_col#1, irq::@3/irq::sin_col#0 ) - [18] irq::i#2 = phi( irq::@17/irq::i#1, irq::@3/0 ) - [19] if(irq::i#2<$28) goto irq::@17 + [19] irq::sin_col#2 = phi( irq::@17/irq::sin_col#1, irq::@3/irq::sin_col#0 ) + [19] irq::i#2 = phi( irq::@17/irq::i#1, irq::@3/0 ) + [20] if(irq::i#2<$28) goto irq::@17 to:irq::@18 irq::@18: scope:[irq] from irq::@16 irq::@19 - [20] irq::l#2 = phi( irq::@16/0, irq::@19/irq::l#1 ) - [21] if(irq::l#2!=RASTER_LINES) goto irq::@19 + [21] irq::l#2 = phi( irq::@16/0, irq::@19/irq::l#1 ) + [22] if(irq::l#2!=RASTER_LINES) goto irq::@19 to:irq::@20 irq::@20: scope:[irq] from irq::@18 - [22] irq::sin_bar#0 = sin_idx + [23] irq::sin_bar#0 = sin_idx to:irq::@21 irq::@21: scope:[irq] from irq::@20 irq::@27 - [23] irq::sin_bar#2 = phi( irq::@20/irq::sin_bar#0, irq::@27/irq::sin_bar#1 ) - [23] irq::barcnt#2 = phi( irq::@20/0, irq::@27/irq::barcnt#1 ) - [24] if(irq::barcnt#2<$10) goto irq::@22 + [24] irq::sin_bar#2 = phi( irq::@20/irq::sin_bar#0, irq::@27/irq::sin_bar#1 ) + [24] irq::barcnt#2 = phi( irq::@20/0, irq::@27/irq::barcnt#1 ) + [25] if(irq::barcnt#2<$10) goto irq::@22 to:irq::@28 irq::@28: scope:[irq] from irq::@21 irq::@29 - [25] irq::i3#2 = phi( irq::@21/0, irq::@29/irq::i3#1 ) - [26] if(irq::i3#2<$13) goto irq::@29 + [26] irq::i3#2 = phi( irq::@21/0, irq::@29/irq::i3#1 ) + [27] if(irq::i3#2<$13) goto irq::@29 to:irq::@30 irq::@30: scope:[irq] from irq::@28 - [27] irq::greet_offset#0 = greet_idx << 4 + [28] irq::greet_offset#0 = greet_idx << 4 to:irq::@31 irq::@31: scope:[irq] from irq::@30 irq::@32 - [28] irq::greet_offset#2 = phi( irq::@30/irq::greet_offset#0, irq::@32/irq::greet_offset#1 ) - [28] irq::i4#2 = phi( irq::@30/0, irq::@32/irq::i4#1 ) - [29] if(irq::i4#2<$10) goto irq::@32 + [29] irq::greet_offset#2 = phi( irq::@30/irq::greet_offset#0, irq::@32/irq::greet_offset#1 ) + [29] irq::i4#2 = phi( irq::@30/0, irq::@32/irq::i4#1 ) + [30] if(irq::i4#2<$10) goto irq::@32 to:irq::@33 irq::@33: scope:[irq] from irq::@31 - [30] scroll_soft = -- scroll_soft - [31] if(scroll_soft!=$ff) goto irq::@return + [31] scroll_soft = -- scroll_soft + [32] if(scroll_soft!=$ff) goto irq::@return to:irq::@34 irq::@34: scope:[irq] from irq::@33 - [32] scroll_soft = 7 + [33] scroll_soft = 7 to:irq::@35 irq::@35: scope:[irq] from irq::@34 irq::@36 - [33] irq::i5#2 = phi( irq::@34/0, irq::@36/irq::i5#1 ) - [34] if(irq::i5#2<$27) goto irq::@36 + [34] irq::i5#2 = phi( irq::@34/0, irq::@36/irq::i5#1 ) + [35] if(irq::i5#2<$27) goto irq::@36 to:irq::@37 irq::@37: scope:[irq] from irq::@35 - [35] irq::nxt#0 = *scroll_ptr - [36] scroll_ptr = ++ scroll_ptr - [37] if(irq::nxt#0!=0) goto irq::@39 + [36] irq::nxt#0 = *scroll_ptr + [37] scroll_ptr = ++ scroll_ptr + [38] if(irq::nxt#0!=0) goto irq::@39 to:irq::@38 irq::@38: scope:[irq] from irq::@37 - [38] scroll_ptr = SCROLL_TEXT - [39] irq::nxt#1 = *scroll_ptr + [39] scroll_ptr = SCROLL_TEXT + [40] irq::nxt#1 = *scroll_ptr to:irq::@39 irq::@39: scope:[irq] from irq::@37 irq::@38 - [40] irq::nxt#2 = phi( irq::@37/irq::nxt#0, irq::@38/irq::nxt#1 ) - [41] irq::$33 = irq::nxt#2 & $bf - [42] *(DEFAULT_SCREEN+SCROLL_ROW*$28+$27) = irq::$33 + [41] irq::nxt#2 = phi( irq::@37/irq::nxt#0, irq::@38/irq::nxt#1 ) + [42] irq::$33 = irq::nxt#2 & $bf + [43] *(DEFAULT_SCREEN+SCROLL_ROW*$28+$27) = irq::$33 to:irq::@return irq::@return: scope:[irq] from irq::@33 irq::@39 - [43] return + [44] return to:@return irq::@36: scope:[irq] from irq::@35 - [44] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] - [45] irq::i5#1 = ++ irq::i5#2 + [45] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] + [46] irq::i5#1 = ++ irq::i5#2 to:irq::@35 irq::@32: scope:[irq] from irq::@31 - [46] irq::$29 = GREETING[irq::greet_offset#2] & $bf - [47] (DEFAULT_SCREEN+GREET_ROW*$28+$d)[irq::i4#2] = irq::$29 - [48] irq::greet_offset#1 = ++ irq::greet_offset#2 - [49] irq::i4#1 = ++ irq::i4#2 + [47] irq::$29 = GREETING[irq::greet_offset#2] & $bf + [48] (DEFAULT_SCREEN+GREET_ROW*$28+$d)[irq::i4#2] = irq::$29 + [49] irq::greet_offset#1 = ++ irq::greet_offset#2 + [50] irq::i4#1 = ++ irq::i4#2 to:irq::@31 irq::@29: scope:[irq] from irq::@28 - [50] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 - [51] irq::$27 = irq::$26 & 7 - [52] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 - [53] irq::i3#1 = ++ irq::i3#2 + [51] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 + [52] irq::$27 = irq::$26 & 7 + [53] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 + [54] irq::i3#1 = ++ irq::i3#2 to:irq::@28 irq::@22: scope:[irq] from irq::@21 - [54] irq::idx#0 = SINE[irq::sin_bar#2] - [55] irq::barcol#0 = irq::barcnt#2 << 4 + [55] irq::idx#0 = SINE[irq::sin_bar#2] + [56] irq::barcol#0 = irq::barcnt#2 << 4 to:irq::@23 irq::@23: scope:[irq] from irq::@22 irq::@24 - [56] irq::idx#3 = phi( irq::@22/irq::idx#0, irq::@24/irq::idx#1 ) - [56] irq::barcol#3 = phi( irq::@22/irq::barcol#0, irq::@24/irq::barcol#1 ) - [56] irq::i1#2 = phi( irq::@22/0, irq::@24/irq::i1#1 ) - [57] if(irq::i1#2<$10) goto irq::@24 + [57] irq::idx#3 = phi( irq::@22/irq::idx#0, irq::@24/irq::idx#1 ) + [57] irq::barcol#3 = phi( irq::@22/irq::barcol#0, irq::@24/irq::barcol#1 ) + [57] irq::i1#2 = phi( irq::@22/0, irq::@24/irq::i1#1 ) + [58] if(irq::i1#2<$10) goto irq::@24 to:irq::@25 irq::@25: scope:[irq] from irq::@23 irq::@26 - [58] irq::idx#4 = phi( irq::@23/irq::idx#3, irq::@26/irq::idx#2 ) - [58] irq::barcol#4 = phi( irq::@23/irq::barcol#3, irq::@26/irq::barcol#2 ) - [58] irq::i2#2 = phi( irq::@23/0, irq::@26/irq::i2#1 ) - [59] if(irq::i2#2<$f) goto irq::@26 + [59] irq::idx#4 = phi( irq::@23/irq::idx#3, irq::@26/irq::idx#2 ) + [59] irq::barcol#4 = phi( irq::@23/irq::barcol#3, irq::@26/irq::barcol#2 ) + [59] irq::i2#2 = phi( irq::@23/0, irq::@26/irq::i2#1 ) + [60] if(irq::i2#2<$f) goto irq::@26 to:irq::@27 irq::@27: scope:[irq] from irq::@25 - [60] irq::sin_bar#1 = irq::sin_bar#2 + $a - [61] irq::barcnt#1 = ++ irq::barcnt#2 + [61] irq::sin_bar#1 = irq::sin_bar#2 + $a + [62] irq::barcnt#1 = ++ irq::barcnt#2 to:irq::@21 irq::@26: scope:[irq] from irq::@25 - [62] irq::barcol#2 = -- irq::barcol#4 - [63] rasters[irq::idx#4] = irq::barcol#2 - [64] irq::idx#2 = ++ irq::idx#4 - [65] irq::i2#1 = ++ irq::i2#2 + [63] irq::barcol#2 = -- irq::barcol#4 + [64] rasters[irq::idx#4] = irq::barcol#2 + [65] irq::idx#2 = ++ irq::idx#4 + [66] irq::i2#1 = ++ irq::i2#2 to:irq::@25 irq::@24: scope:[irq] from irq::@23 - [66] rasters[irq::idx#3] = irq::barcol#3 - [67] irq::idx#1 = ++ irq::idx#3 - [68] irq::barcol#1 = ++ irq::barcol#3 - [69] irq::i1#1 = ++ irq::i1#2 + [67] rasters[irq::idx#3] = irq::barcol#3 + [68] irq::idx#1 = ++ irq::idx#3 + [69] irq::barcol#1 = ++ irq::barcol#3 + [70] irq::i1#1 = ++ irq::i1#2 to:irq::@23 irq::@19: scope:[irq] from irq::@18 - [70] rasters[irq::l#2] = 0 - [71] irq::l#1 = ++ irq::l#2 + [71] rasters[irq::l#2] = 0 + [72] irq::l#1 = ++ irq::l#2 to:irq::@18 irq::@17: scope:[irq] from irq::@16 - [72] irq::col1#0 = SINE[irq::sin_col#2] >> 2 - [73] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 - [74] irq::col1#1 = irq::col1#0 >> 1 - [75] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 - [76] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 - [77] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 - [78] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 - [79] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 - [80] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 - [81] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] - [82] irq::sin_col#1 = ++ irq::sin_col#2 - [83] irq::i#1 = ++ irq::i#2 + [73] irq::col1#0 = SINE[irq::sin_col#2] >> 2 + [74] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 + [75] irq::col1#1 = irq::col1#0 >> 1 + [76] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 + [77] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 + [78] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 + [79] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 + [80] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 + [81] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 + [82] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] + [83] irq::sin_col#1 = ++ irq::sin_col#2 + [84] irq::i#1 = ++ irq::i#2 to:irq::@16 irq::@2: scope:[irq] from irq::@1 - [84] irq::col#0 = rasters[irq::line#10] - [85] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR) = irq::col#0 - [86] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR) = irq::col#0 - [87] if(irq::line#10> 1 - [51] irq::$27 = irq::$26 & 7 - [52] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 - [53] irq::i3#1 = ++ irq::i3#2 + [51] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 + [52] irq::$27 = irq::$26 & 7 + [53] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 + [54] irq::i3#1 = ++ irq::i3#2 to:irq::@28 irq::@22: scope:[irq] from irq::@21 - [54] irq::idx#0 = SINE[irq::sin_bar#2] - [55] irq::barcol#0 = irq::barcnt#2 << 4 + [55] irq::idx#0 = SINE[irq::sin_bar#2] + [56] irq::barcol#0 = irq::barcnt#2 << 4 to:irq::@23 irq::@23: scope:[irq] from irq::@22 irq::@24 - [56] irq::idx#3 = phi( irq::@22/irq::idx#0, irq::@24/irq::idx#1 ) - [56] irq::barcol#3 = phi( irq::@22/irq::barcol#0, irq::@24/irq::barcol#1 ) - [56] irq::i1#2 = phi( irq::@22/0, irq::@24/irq::i1#1 ) - [57] if(irq::i1#2<$10) goto irq::@24 + [57] irq::idx#3 = phi( irq::@22/irq::idx#0, irq::@24/irq::idx#1 ) + [57] irq::barcol#3 = phi( irq::@22/irq::barcol#0, irq::@24/irq::barcol#1 ) + [57] irq::i1#2 = phi( irq::@22/0, irq::@24/irq::i1#1 ) + [58] if(irq::i1#2<$10) goto irq::@24 to:irq::@25 irq::@25: scope:[irq] from irq::@23 irq::@26 - [58] irq::idx#4 = phi( irq::@23/irq::idx#3, irq::@26/irq::idx#2 ) - [58] irq::barcol#4 = phi( irq::@23/irq::barcol#3, irq::@26/irq::barcol#2 ) - [58] irq::i2#2 = phi( irq::@23/0, irq::@26/irq::i2#1 ) - [59] if(irq::i2#2<$f) goto irq::@26 + [59] irq::idx#4 = phi( irq::@23/irq::idx#3, irq::@26/irq::idx#2 ) + [59] irq::barcol#4 = phi( irq::@23/irq::barcol#3, irq::@26/irq::barcol#2 ) + [59] irq::i2#2 = phi( irq::@23/0, irq::@26/irq::i2#1 ) + [60] if(irq::i2#2<$f) goto irq::@26 to:irq::@27 irq::@27: scope:[irq] from irq::@25 - [60] irq::sin_bar#1 = irq::sin_bar#2 + $a - [61] irq::barcnt#1 = ++ irq::barcnt#2 + [61] irq::sin_bar#1 = irq::sin_bar#2 + $a + [62] irq::barcnt#1 = ++ irq::barcnt#2 to:irq::@21 irq::@26: scope:[irq] from irq::@25 - [62] irq::barcol#2 = -- irq::barcol#4 - [63] rasters[irq::idx#4] = irq::barcol#2 - [64] irq::idx#2 = ++ irq::idx#4 - [65] irq::i2#1 = ++ irq::i2#2 + [63] irq::barcol#2 = -- irq::barcol#4 + [64] rasters[irq::idx#4] = irq::barcol#2 + [65] irq::idx#2 = ++ irq::idx#4 + [66] irq::i2#1 = ++ irq::i2#2 to:irq::@25 irq::@24: scope:[irq] from irq::@23 - [66] rasters[irq::idx#3] = irq::barcol#3 - [67] irq::idx#1 = ++ irq::idx#3 - [68] irq::barcol#1 = ++ irq::barcol#3 - [69] irq::i1#1 = ++ irq::i1#2 + [67] rasters[irq::idx#3] = irq::barcol#3 + [68] irq::idx#1 = ++ irq::idx#3 + [69] irq::barcol#1 = ++ irq::barcol#3 + [70] irq::i1#1 = ++ irq::i1#2 to:irq::@23 irq::@19: scope:[irq] from irq::@18 - [70] rasters[irq::l#2] = 0 - [71] irq::l#1 = ++ irq::l#2 + [71] rasters[irq::l#2] = 0 + [72] irq::l#1 = ++ irq::l#2 to:irq::@18 irq::@17: scope:[irq] from irq::@16 - [72] irq::col1#0 = SINE[irq::sin_col#2] >> 2 - [73] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 - [74] irq::col1#1 = irq::col1#0 >> 1 - [75] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 - [76] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 - [77] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 - [78] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 - [79] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 - [80] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 - [81] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] - [82] irq::sin_col#1 = ++ irq::sin_col#2 - [83] irq::i#1 = ++ irq::i#2 + [73] irq::col1#0 = SINE[irq::sin_col#2] >> 2 + [74] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 + [75] irq::col1#1 = irq::col1#0 >> 1 + [76] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 + [77] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 + [78] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 + [79] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 + [80] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 + [81] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 + [82] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] + [83] irq::sin_col#1 = ++ irq::sin_col#2 + [84] irq::i#1 = ++ irq::i#2 to:irq::@16 irq::@2: scope:[irq] from irq::@1 - [84] irq::col#0 = rasters[irq::line#10] - [85] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR) = irq::col#0 - [86] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR) = irq::col#0 - [87] if(irq::line#10> 1 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] { } ) always clobbers reg byte a +Statement [51] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:9 [ irq::i3#2 irq::i3#1 ] -Statement [51] irq::$27 = irq::$26 & 7 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] { } ) always clobbers reg byte a -Statement [55] irq::barcol#0 = irq::barcnt#2 << 4 [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] { } ) always clobbers reg byte a +Statement [52] irq::$27 = irq::$26 & 7 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] { } ) always clobbers reg byte a +Statement [56] irq::barcol#0 = irq::barcnt#2 << 4 [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:7 [ irq::barcnt#2 irq::barcnt#1 ] Removing always clobbered register reg byte a as potential for zp[1]:8 [ irq::sin_bar#2 irq::sin_bar#0 irq::sin_bar#1 ] Removing always clobbered register reg byte a as potential for zp[1]:17 [ irq::idx#4 irq::idx#3 irq::idx#0 irq::idx#1 irq::idx#2 ] -Statement [60] irq::sin_bar#1 = irq::sin_bar#2 + $a [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] { } ) always clobbers reg byte a -Statement [70] rasters[irq::l#2] = 0 [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] { } ) always clobbers reg byte a +Statement [61] irq::sin_bar#1 = irq::sin_bar#2 + $a [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] { } ) always clobbers reg byte a +Statement [71] rasters[irq::l#2] = 0 [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:6 [ irq::l#2 irq::l#1 ] -Statement [72] irq::col1#0 = SINE[irq::sin_col#2] >> 2 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] { } ) always clobbers reg byte a +Statement [73] irq::col1#0 = SINE[irq::sin_col#2] >> 2 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:4 [ irq::i#2 irq::i#1 ] Removing always clobbered register reg byte a as potential for zp[1]:5 [ irq::sin_col#2 irq::sin_col#1 irq::sin_col#0 ] -Statement [74] irq::col1#1 = irq::col1#0 >> 1 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] { } ) always clobbers reg byte a -Statement [81] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] { } ) always clobbers reg byte a -Statement [96] if(greet_zoomx!=0) goto irq::@7 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [75] irq::col1#1 = irq::col1#0 >> 1 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] { } ) always clobbers reg byte a +Statement [82] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] { } ) always clobbers reg byte a +Statement [97] if(greet_zoomx!=0) goto irq::@7 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ irq::line#10 irq::line#1 ] Removing always clobbered register reg byte a as potential for zp[1]:3 [ irq::wobble_idx#10 irq::wobble_idx#0 irq::wobble_idx#7 irq::wobble_idx#1 ] -Statement [98] if(greet_idx!=GREET_COUNT) goto irq::@7 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [99] greet_idx = 0 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [104] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [106] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [107] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [109] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] { } ) always clobbers reg byte a -Statement [110] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [112] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [99] if(greet_idx!=GREET_COUNT) goto irq::@7 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [100] greet_idx = 0 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [106] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [107] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [108] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [110] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] { } ) always clobbers reg byte a +Statement [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [112] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [114] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a Statement asm { lda#0 } always clobbers reg byte a -Statement [115] call *songInit [ ] ( main:7 [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [122] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [116] callexecute *songInit [ ] ( main:7 [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [123] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:20 [ main::i#2 main::i#1 ] -Statement [123] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a -Statement [124] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a -Statement [128] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [129] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [132] *HARDWARE_IRQ = &irq [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [133] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [134] *PROCPORT = PROCPORT_RAM_IO [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [135] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [138] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' [ main::i2#2 ] ( main:7 [ main::i2#2 ] { } ) always clobbers reg byte a +Statement [124] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [125] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [129] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [132] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [133] *HARDWARE_IRQ = &irq [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [134] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [135] *PROCPORT = PROCPORT_RAM_IO [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [136] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [139] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' [ main::i2#2 ] ( main:7 [ main::i2#2 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:19 [ main::i2#2 main::i2#1 ] -Statement [140] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] [ main::i1#2 ] ( main:7 [ main::i1#2 ] { } ) always clobbers reg byte a +Statement [141] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] [ main::i1#2 ] ( main:7 [ main::i1#2 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:18 [ main::i1#2 main::i1#1 ] -Statement [144] if(memset::dst#2!=memset::end#0) goto memset::@2 [ memset::dst#2 ] ( main:7::memset:116 [ memset::dst#2 ] { } ) always clobbers reg byte a -Statement [146] *memset::dst#2 = memset::c#0 [ memset::dst#2 ] ( main:7::memset:116 [ memset::dst#2 ] { } ) always clobbers reg byte a reg byte y +Statement [145] if(memset::dst#2!=memset::end#0) goto memset::@2 [ memset::dst#2 ] ( main:7::memset:117 [ memset::dst#2 ] { } ) always clobbers reg byte a +Statement [147] *memset::dst#2 = memset::c#0 [ memset::dst#2 ] ( main:7::memset:117 [ memset::dst#2 ] { } ) always clobbers reg byte a reg byte y Statement [1] sin_idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] scroll_soft = 7 [ ] ( [ ] { } ) always clobbers reg byte a Statement [3] scroll_ptr = SCROLL_TEXT [ ] ( [ ] { } ) always clobbers reg byte a Statement [4] greet_zoomx = 0 [ ] ( [ ] { } ) always clobbers reg byte a Statement [5] greet_idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [9] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_RASLINE0) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_RASLINE0) | $80 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx ] { } ) always clobbers reg byte a -Statement [10] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx ] { } ) always clobbers reg byte a -Statement [11] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = 0 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx ] { } ) always clobbers reg byte a -Statement [16] call *songPlay [ sin_idx scroll_soft scroll_ptr greet_idx ] ( [ sin_idx scroll_soft scroll_ptr greet_idx ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [27] irq::greet_offset#0 = greet_idx << 4 [ scroll_soft scroll_ptr irq::greet_offset#0 ] ( [ scroll_soft scroll_ptr irq::greet_offset#0 ] { } ) always clobbers reg byte a -Statement [31] if(scroll_soft!=$ff) goto irq::@return [ scroll_ptr ] ( [ scroll_ptr ] { } ) always clobbers reg byte a -Statement [32] scroll_soft = 7 [ scroll_ptr ] ( [ scroll_ptr ] { } ) always clobbers reg byte a -Statement [35] irq::nxt#0 = *scroll_ptr [ scroll_ptr irq::nxt#0 ] ( [ scroll_ptr irq::nxt#0 ] { } ) always clobbers reg byte a reg byte y -Statement [38] scroll_ptr = SCROLL_TEXT [ scroll_ptr ] ( [ scroll_ptr ] { } ) always clobbers reg byte a -Statement [39] irq::nxt#1 = *scroll_ptr [ irq::nxt#1 ] ( [ irq::nxt#1 ] { } ) always clobbers reg byte a reg byte y -Statement [41] irq::$33 = irq::nxt#2 & $bf [ irq::$33 ] ( [ irq::$33 ] { } ) always clobbers reg byte a -Statement [43] return [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [44] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] [ scroll_ptr irq::i5#2 ] ( [ scroll_ptr irq::i5#2 ] { } ) always clobbers reg byte a -Statement [46] irq::$29 = GREETING[irq::greet_offset#2] & $bf [ scroll_soft scroll_ptr irq::i4#2 irq::greet_offset#2 irq::$29 ] ( [ scroll_soft scroll_ptr irq::i4#2 irq::greet_offset#2 irq::$29 ] { } ) always clobbers reg byte a -Statement [50] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] { } ) always clobbers reg byte a -Statement [51] irq::$27 = irq::$26 & 7 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] { } ) always clobbers reg byte a -Statement [55] irq::barcol#0 = irq::barcnt#2 << 4 [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] { } ) always clobbers reg byte a -Statement [60] irq::sin_bar#1 = irq::sin_bar#2 + $a [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] { } ) always clobbers reg byte a -Statement [70] rasters[irq::l#2] = 0 [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] { } ) always clobbers reg byte a -Statement [72] irq::col1#0 = SINE[irq::sin_col#2] >> 2 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] { } ) always clobbers reg byte a -Statement [74] irq::col1#1 = irq::col1#0 >> 1 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] { } ) always clobbers reg byte a -Statement [81] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] { } ) always clobbers reg byte a -Statement [96] if(greet_zoomx!=0) goto irq::@7 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [98] if(greet_idx!=GREET_COUNT) goto irq::@7 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [99] greet_idx = 0 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [104] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [106] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [107] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a -Statement [109] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] ( [ sin_idx scroll_soft scroll_ptr greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] { } ) always clobbers reg byte a -Statement [110] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [112] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [9] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_RASLINE0) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_RASLINE0) | $80 [ sin_idx scroll_soft greet_zoomx greet_idx ] ( [ sin_idx scroll_soft greet_zoomx greet_idx ] { } ) always clobbers reg byte a +Statement [10] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) = IRQ_RASTER [ sin_idx scroll_soft greet_zoomx greet_idx ] ( [ sin_idx scroll_soft greet_zoomx greet_idx ] { } ) always clobbers reg byte a +Statement [11] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = 0 [ sin_idx scroll_soft greet_zoomx greet_idx ] ( [ sin_idx scroll_soft greet_zoomx greet_idx ] { } ) always clobbers reg byte a +Statement [17] callexecute *songPlay [ sin_idx scroll_soft scroll_ptr greet_idx ] ( [ sin_idx scroll_soft scroll_ptr greet_idx ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [28] irq::greet_offset#0 = greet_idx << 4 [ scroll_soft scroll_ptr irq::greet_offset#0 ] ( [ scroll_soft scroll_ptr irq::greet_offset#0 ] { } ) always clobbers reg byte a +Statement [32] if(scroll_soft!=$ff) goto irq::@return [ scroll_ptr ] ( [ scroll_ptr ] { } ) always clobbers reg byte a +Statement [33] scroll_soft = 7 [ scroll_ptr ] ( [ scroll_ptr ] { } ) always clobbers reg byte a +Statement [36] irq::nxt#0 = *scroll_ptr [ scroll_ptr irq::nxt#0 ] ( [ scroll_ptr irq::nxt#0 ] { } ) always clobbers reg byte a reg byte y +Statement [39] scroll_ptr = SCROLL_TEXT [ scroll_ptr ] ( [ scroll_ptr ] { } ) always clobbers reg byte a +Statement [40] irq::nxt#1 = *scroll_ptr [ irq::nxt#1 ] ( [ irq::nxt#1 ] { } ) always clobbers reg byte a reg byte y +Statement [42] irq::$33 = irq::nxt#2 & $bf [ irq::$33 ] ( [ irq::$33 ] { } ) always clobbers reg byte a +Statement [44] return [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [45] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] [ scroll_ptr irq::i5#2 ] ( [ scroll_ptr irq::i5#2 ] { } ) always clobbers reg byte a +Statement [47] irq::$29 = GREETING[irq::greet_offset#2] & $bf [ scroll_soft scroll_ptr irq::i4#2 irq::greet_offset#2 irq::$29 ] ( [ scroll_soft scroll_ptr irq::i4#2 irq::greet_offset#2 irq::$29 ] { } ) always clobbers reg byte a +Statement [51] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$26 ] { } ) always clobbers reg byte a +Statement [52] irq::$27 = irq::$26 & 7 [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] ( [ scroll_soft scroll_ptr greet_idx irq::i3#2 irq::$27 ] { } ) always clobbers reg byte a +Statement [56] irq::barcol#0 = irq::barcnt#2 << 4 [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#2 irq::idx#0 irq::barcol#0 ] { } ) always clobbers reg byte a +Statement [61] irq::sin_bar#1 = irq::sin_bar#2 + $a [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] ( [ scroll_soft scroll_ptr greet_idx irq::barcnt#2 irq::sin_bar#1 ] { } ) always clobbers reg byte a +Statement [71] rasters[irq::l#2] = 0 [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::l#2 ] { } ) always clobbers reg byte a +Statement [73] irq::col1#0 = SINE[irq::sin_col#2] >> 2 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#0 ] { } ) always clobbers reg byte a +Statement [75] irq::col1#1 = irq::col1#0 >> 1 [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 irq::col1#1 ] { } ) always clobbers reg byte a +Statement [82] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] ( [ sin_idx scroll_soft scroll_ptr greet_idx irq::i#2 irq::sin_col#2 ] { } ) always clobbers reg byte a +Statement [97] if(greet_zoomx!=0) goto irq::@7 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [99] if(greet_idx!=GREET_COUNT) goto irq::@7 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [100] greet_idx = 0 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [106] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [107] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [108] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#10 ] { } ) always clobbers reg byte a +Statement [110] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] ( [ scroll_soft greet_zoomx greet_idx irq::line#10 irq::wobble_idx#1 ] { } ) always clobbers reg byte a +Statement [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [112] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [114] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 [ ] ( main:7 [ ] { } ) always clobbers reg byte a Statement asm { lda#0 } always clobbers reg byte a -Statement [115] call *songInit [ ] ( main:7 [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z -Statement [122] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a -Statement [123] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a -Statement [124] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a -Statement [128] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [129] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [132] *HARDWARE_IRQ = &irq [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [133] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [134] *PROCPORT = PROCPORT_RAM_IO [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [135] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ ] ( main:7 [ ] { } ) always clobbers reg byte a -Statement [138] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' [ main::i2#2 ] ( main:7 [ main::i2#2 ] { } ) always clobbers reg byte a -Statement [140] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] [ main::i1#2 ] ( main:7 [ main::i1#2 ] { } ) always clobbers reg byte a -Statement [144] if(memset::dst#2!=memset::end#0) goto memset::@2 [ memset::dst#2 ] ( main:7::memset:116 [ memset::dst#2 ] { } ) always clobbers reg byte a -Statement [146] *memset::dst#2 = memset::c#0 [ memset::dst#2 ] ( main:7::memset:116 [ memset::dst#2 ] { } ) always clobbers reg byte a reg byte y +Statement [116] callexecute *songInit [ ] ( main:7 [ ] { } ) always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [123] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [124] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [125] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] [ main::i#2 ] ( main:7 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [129] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [132] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [133] *HARDWARE_IRQ = &irq [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [134] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [135] *PROCPORT = PROCPORT_RAM_IO [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [136] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 [ ] ( main:7 [ ] { } ) always clobbers reg byte a +Statement [139] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' [ main::i2#2 ] ( main:7 [ main::i2#2 ] { } ) always clobbers reg byte a +Statement [141] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] [ main::i1#2 ] ( main:7 [ main::i1#2 ] { } ) always clobbers reg byte a +Statement [145] if(memset::dst#2!=memset::end#0) goto memset::@2 [ memset::dst#2 ] ( main:7::memset:117 [ memset::dst#2 ] { } ) always clobbers reg byte a +Statement [147] *memset::dst#2 = memset::c#0 [ memset::dst#2 ] ( main:7::memset:117 [ memset::dst#2 ] { } ) always clobbers reg byte a reg byte y Potential registers zp[1]:2 [ irq::line#10 irq::line#1 ] : zp[1]:2 , reg byte x , reg byte y , reg byte z , Potential registers zp[1]:3 [ irq::wobble_idx#10 irq::wobble_idx#0 irq::wobble_idx#7 irq::wobble_idx#1 ] : zp[1]:3 , reg byte x , reg byte y , reg byte z , Potential registers zp[1]:4 [ irq::i#2 irq::i#1 ] : zp[1]:4 , reg byte x , reg byte y , reg byte z , @@ -1958,7 +1964,7 @@ REGISTER UPLIFT SCOPES Uplift Scope [memset] 3,336.67: zp[2]:21 [ memset::dst#2 memset::dst#1 ] Uplift Scope [irq] 454: zp[1]:16 [ irq::barcol#4 irq::barcol#3 irq::barcol#0 irq::barcol#1 irq::barcol#2 ] 418.67: zp[1]:17 [ irq::idx#4 irq::idx#3 irq::idx#0 irq::idx#1 irq::idx#2 ] 262.6: zp[1]:14 [ irq::i1#2 irq::i1#1 ] 262.6: zp[1]:15 [ irq::i2#2 irq::i2#1 ] 56: zp[1]:38 [ irq::raster#0 ] 41.59: zp[1]:3 [ irq::wobble_idx#10 irq::wobble_idx#0 irq::wobble_idx#7 irq::wobble_idx#1 ] 40.33: zp[1]:12 [ irq::i5#2 irq::i5#1 ] 36.67: zp[1]:6 [ irq::l#2 irq::l#1 ] 33: zp[1]:9 [ irq::i3#2 irq::i3#1 ] 31.31: zp[1]:4 [ irq::i#2 irq::i#1 ] 30.8: zp[1]:10 [ irq::i4#2 irq::i4#1 ] 25.26: zp[1]:2 [ irq::line#10 irq::line#1 ] 24.59: zp[1]:7 [ irq::barcnt#2 irq::barcnt#1 ] 23.75: zp[1]:11 [ irq::greet_offset#2 irq::greet_offset#0 irq::greet_offset#1 ] 22: zp[1]:30 [ irq::$29 ] 22: zp[1]:31 [ irq::$26 ] 22: zp[1]:32 [ irq::$27 ] 22: zp[1]:37 [ irq::$10 ] 18.83: zp[1]:5 [ irq::sin_col#2 irq::sin_col#1 irq::sin_col#0 ] 17.19: zp[1]:8 [ irq::sin_bar#2 irq::sin_bar#0 irq::sin_bar#1 ] 16.5: zp[1]:33 [ irq::col1#0 ] 16.5: zp[1]:35 [ irq::col#0 ] 12.83: zp[1]:34 [ irq::col1#1 ] 12: zp[1]:13 [ irq::nxt#2 irq::nxt#0 irq::nxt#1 ] 11: zp[1]:36 [ irq::zoomval#0 ] 4: zp[1]:29 [ irq::$33 ] Uplift Scope [main] 370.33: zp[1]:18 [ main::i1#2 main::i1#1 ] 353.5: zp[1]:20 [ main::i#2 main::i#1 ] 336.67: zp[1]:19 [ main::i2#2 main::i2#1 ] -Uplift Scope [] 1.39: zp[1]:27 [ greet_zoomx ] 0.62: zp[1]:28 [ greet_idx ] 0.24: zp[1]:24 [ scroll_soft ] 0.23: zp[1]:23 [ sin_idx ] 0.13: zp[2]:25 [ scroll_ptr ] +Uplift Scope [] 1.39: zp[1]:27 [ greet_zoomx ] 0.62: zp[1]:28 [ greet_idx ] 0.5: zp[1]:23 [ sin_idx ] 0.24: zp[1]:24 [ scroll_soft ] 0.2: zp[2]:25 [ scroll_ptr ] Uplift Scope [MOS6526_CIA] Uplift Scope [MOS6569_VICII] Uplift Scope [MOS6581_SID] @@ -1969,78 +1975,78 @@ Uplift Scope [DMA_LIST_F018A] Uplift Scope [DMA_LIST_F018B] Uplift Scope [__start] -Uplifting [memset] best 19116 combination zp[2]:21 [ memset::dst#2 memset::dst#1 ] -Uplifting [main] best 18716 combination reg byte x [ main::i1#2 main::i1#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte x [ main::i2#2 main::i2#1 ] -Uplifting [] best 18716 combination zp[1]:27 [ greet_zoomx ] zp[1]:28 [ greet_idx ] zp[1]:24 [ scroll_soft ] zp[1]:23 [ sin_idx ] zp[2]:25 [ scroll_ptr ] -Uplifting [MOS6526_CIA] best 18716 combination -Uplifting [MOS6569_VICII] best 18716 combination -Uplifting [MOS6581_SID] best 18716 combination -Uplifting [MOS4569_VICIII] best 18716 combination -Uplifting [MEGA65_VICIV] best 18716 combination -Uplifting [F018_DMAGIC] best 18716 combination -Uplifting [DMA_LIST_F018A] best 18716 combination -Uplifting [DMA_LIST_F018B] best 18716 combination -Uplifting [__start] best 18716 combination +Uplifting [memset] best 19089 combination zp[2]:21 [ memset::dst#2 memset::dst#1 ] +Uplifting [main] best 18689 combination reg byte x [ main::i1#2 main::i1#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte x [ main::i2#2 main::i2#1 ] +Uplifting [] best 18689 combination zp[1]:27 [ greet_zoomx ] zp[1]:28 [ greet_idx ] zp[1]:23 [ sin_idx ] zp[1]:24 [ scroll_soft ] zp[2]:25 [ scroll_ptr ] +Uplifting [MOS6526_CIA] best 18689 combination +Uplifting [MOS6569_VICII] best 18689 combination +Uplifting [MOS6581_SID] best 18689 combination +Uplifting [MOS4569_VICIII] best 18689 combination +Uplifting [MEGA65_VICIV] best 18689 combination +Uplifting [F018_DMAGIC] best 18689 combination +Uplifting [DMA_LIST_F018A] best 18689 combination +Uplifting [DMA_LIST_F018B] best 18689 combination +Uplifting [__start] best 18689 combination Attempting to uplift remaining variables inzp[1]:16 [ irq::barcol#4 irq::barcol#3 irq::barcol#0 irq::barcol#1 irq::barcol#2 ] -Uplifting [irq] best 17496 combination reg byte z [ irq::barcol#4 irq::barcol#3 irq::barcol#0 irq::barcol#1 irq::barcol#2 ] +Uplifting [irq] best 17469 combination reg byte z [ irq::barcol#4 irq::barcol#3 irq::barcol#0 irq::barcol#1 irq::barcol#2 ] Attempting to uplift remaining variables inzp[1]:17 [ irq::idx#4 irq::idx#3 irq::idx#0 irq::idx#1 irq::idx#2 ] -Uplifting [irq] best 16266 combination reg byte x [ irq::idx#4 irq::idx#3 irq::idx#0 irq::idx#1 irq::idx#2 ] +Uplifting [irq] best 16239 combination reg byte x [ irq::idx#4 irq::idx#3 irq::idx#0 irq::idx#1 irq::idx#2 ] Attempting to uplift remaining variables inzp[1]:14 [ irq::i1#2 irq::i1#1 ] -Uplifting [irq] best 15366 combination reg byte y [ irq::i1#2 irq::i1#1 ] +Uplifting [irq] best 15339 combination reg byte y [ irq::i1#2 irq::i1#1 ] Attempting to uplift remaining variables inzp[1]:15 [ irq::i2#2 irq::i2#1 ] -Uplifting [irq] best 14466 combination reg byte y [ irq::i2#2 irq::i2#1 ] +Uplifting [irq] best 14439 combination reg byte y [ irq::i2#2 irq::i2#1 ] Attempting to uplift remaining variables inzp[1]:38 [ irq::raster#0 ] -Uplifting [irq] best 14136 combination reg byte a [ irq::raster#0 ] +Uplifting [irq] best 14109 combination reg byte a [ irq::raster#0 ] Attempting to uplift remaining variables inzp[1]:3 [ irq::wobble_idx#10 irq::wobble_idx#0 irq::wobble_idx#7 irq::wobble_idx#1 ] -Uplifting [irq] best 14073 combination reg byte x [ irq::wobble_idx#10 irq::wobble_idx#0 irq::wobble_idx#7 irq::wobble_idx#1 ] +Uplifting [irq] best 14046 combination reg byte x [ irq::wobble_idx#10 irq::wobble_idx#0 irq::wobble_idx#7 irq::wobble_idx#1 ] Attempting to uplift remaining variables inzp[1]:12 [ irq::i5#2 irq::i5#1 ] -Uplifting [irq] best 13953 combination reg byte x [ irq::i5#2 irq::i5#1 ] +Uplifting [irq] best 13926 combination reg byte x [ irq::i5#2 irq::i5#1 ] Attempting to uplift remaining variables inzp[1]:6 [ irq::l#2 irq::l#1 ] -Uplifting [irq] best 13833 combination reg byte x [ irq::l#2 irq::l#1 ] +Uplifting [irq] best 13806 combination reg byte x [ irq::l#2 irq::l#1 ] Attempting to uplift remaining variables inzp[1]:9 [ irq::i3#2 irq::i3#1 ] -Uplifting [irq] best 13683 combination reg byte x [ irq::i3#2 irq::i3#1 ] +Uplifting [irq] best 13656 combination reg byte x [ irq::i3#2 irq::i3#1 ] Attempting to uplift remaining variables inzp[1]:4 [ irq::i#2 irq::i#1 ] -Uplifting [irq] best 13353 combination reg byte x [ irq::i#2 irq::i#1 ] +Uplifting [irq] best 13326 combination reg byte x [ irq::i#2 irq::i#1 ] Attempting to uplift remaining variables inzp[1]:10 [ irq::i4#2 irq::i4#1 ] -Uplifting [irq] best 13233 combination reg byte x [ irq::i4#2 irq::i4#1 ] +Uplifting [irq] best 13206 combination reg byte x [ irq::i4#2 irq::i4#1 ] Attempting to uplift remaining variables inzp[1]:2 [ irq::line#10 irq::line#1 ] -Uplifting [irq] best 13013 combination reg byte z [ irq::line#10 irq::line#1 ] +Uplifting [irq] best 12986 combination reg byte z [ irq::line#10 irq::line#1 ] Attempting to uplift remaining variables inzp[1]:7 [ irq::barcnt#2 irq::barcnt#1 ] -Uplifting [irq] best 13013 combination zp[1]:7 [ irq::barcnt#2 irq::barcnt#1 ] +Uplifting [irq] best 12986 combination zp[1]:7 [ irq::barcnt#2 irq::barcnt#1 ] Attempting to uplift remaining variables inzp[1]:11 [ irq::greet_offset#2 irq::greet_offset#0 irq::greet_offset#1 ] -Uplifting [irq] best 12952 combination reg byte y [ irq::greet_offset#2 irq::greet_offset#0 irq::greet_offset#1 ] +Uplifting [irq] best 12925 combination reg byte y [ irq::greet_offset#2 irq::greet_offset#0 irq::greet_offset#1 ] Attempting to uplift remaining variables inzp[1]:30 [ irq::$29 ] -Uplifting [irq] best 12892 combination reg byte a [ irq::$29 ] +Uplifting [irq] best 12865 combination reg byte a [ irq::$29 ] Attempting to uplift remaining variables inzp[1]:31 [ irq::$26 ] -Uplifting [irq] best 12832 combination reg byte a [ irq::$26 ] +Uplifting [irq] best 12805 combination reg byte a [ irq::$26 ] Attempting to uplift remaining variables inzp[1]:32 [ irq::$27 ] -Uplifting [irq] best 12772 combination reg byte a [ irq::$27 ] +Uplifting [irq] best 12745 combination reg byte a [ irq::$27 ] Attempting to uplift remaining variables inzp[1]:37 [ irq::$10 ] -Uplifting [irq] best 12712 combination reg byte a [ irq::$10 ] +Uplifting [irq] best 12685 combination reg byte a [ irq::$10 ] Attempting to uplift remaining variables inzp[1]:5 [ irq::sin_col#2 irq::sin_col#1 irq::sin_col#0 ] -Uplifting [irq] best 12619 combination reg byte y [ irq::sin_col#2 irq::sin_col#1 irq::sin_col#0 ] +Uplifting [irq] best 12592 combination reg byte y [ irq::sin_col#2 irq::sin_col#1 irq::sin_col#0 ] Attempting to uplift remaining variables inzp[1]:8 [ irq::sin_bar#2 irq::sin_bar#0 irq::sin_bar#1 ] -Uplifting [irq] best 12619 combination zp[1]:8 [ irq::sin_bar#2 irq::sin_bar#0 irq::sin_bar#1 ] +Uplifting [irq] best 12592 combination zp[1]:8 [ irq::sin_bar#2 irq::sin_bar#0 irq::sin_bar#1 ] Attempting to uplift remaining variables inzp[1]:33 [ irq::col1#0 ] -Uplifting [irq] best 12529 combination reg byte a [ irq::col1#0 ] +Uplifting [irq] best 12502 combination reg byte a [ irq::col1#0 ] Attempting to uplift remaining variables inzp[1]:35 [ irq::col#0 ] -Uplifting [irq] best 12439 combination reg byte a [ irq::col#0 ] +Uplifting [irq] best 12412 combination reg byte a [ irq::col#0 ] Attempting to uplift remaining variables inzp[1]:34 [ irq::col1#1 ] -Uplifting [irq] best 12229 combination reg byte a [ irq::col1#1 ] +Uplifting [irq] best 12202 combination reg byte a [ irq::col1#1 ] Attempting to uplift remaining variables inzp[1]:13 [ irq::nxt#2 irq::nxt#0 irq::nxt#1 ] -Uplifting [irq] best 12219 combination reg byte a [ irq::nxt#2 irq::nxt#0 irq::nxt#1 ] +Uplifting [irq] best 12192 combination reg byte a [ irq::nxt#2 irq::nxt#0 irq::nxt#1 ] Attempting to uplift remaining variables inzp[1]:36 [ irq::zoomval#0 ] -Uplifting [irq] best 12129 combination reg byte a [ irq::zoomval#0 ] +Uplifting [irq] best 12102 combination reg byte a [ irq::zoomval#0 ] Attempting to uplift remaining variables inzp[1]:29 [ irq::$33 ] -Uplifting [irq] best 12123 combination reg byte a [ irq::$33 ] +Uplifting [irq] best 12096 combination reg byte a [ irq::$33 ] Attempting to uplift remaining variables inzp[1]:27 [ greet_zoomx ] -Uplifting [] best 12123 combination zp[1]:27 [ greet_zoomx ] +Uplifting [] best 12096 combination zp[1]:27 [ greet_zoomx ] Attempting to uplift remaining variables inzp[1]:28 [ greet_idx ] -Uplifting [] best 12123 combination zp[1]:28 [ greet_idx ] -Attempting to uplift remaining variables inzp[1]:24 [ scroll_soft ] -Uplifting [] best 12123 combination zp[1]:24 [ scroll_soft ] +Uplifting [] best 12096 combination zp[1]:28 [ greet_idx ] Attempting to uplift remaining variables inzp[1]:23 [ sin_idx ] -Uplifting [] best 12123 combination zp[1]:23 [ sin_idx ] +Uplifting [] best 12096 combination zp[1]:23 [ sin_idx ] +Attempting to uplift remaining variables inzp[1]:24 [ scroll_soft ] +Uplifting [] best 12096 combination zp[1]:24 [ scroll_soft ] Allocated (was zp[1]:7) zp[1]:2 [ irq::barcnt#2 irq::barcnt#1 ] Allocated (was zp[1]:8) zp[1]:3 [ irq::sin_bar#2 irq::sin_bar#0 irq::sin_bar#1 ] Allocated (was zp[2]:21) zp[2]:4 [ memset::dst#2 memset::dst#1 ] @@ -2233,72 +2239,74 @@ irq: { // [15] if(irq::line#10!=RASTER_LINES) goto irq::@2 -- vbuzz_neq_vbuc1_then_la1 cpz #RASTER_LINES bne __b2 + // [16] phi from irq::@1 to irq::@3 [phi:irq::@1->irq::@3] + __b3_from___b1: jmp __b3 // irq::@3 __b3: - // [16] call *songPlay + // [17] callexecute *songPlay // play music jsr songPlay - // [17] irq::sin_col#0 = sin_idx -- vbuyy=vbuz1 + // [18] irq::sin_col#0 = sin_idx -- vbuyy=vbuz1 // Set up colors behind logo, scroll and greets ldy.z sin_idx - // [18] phi from irq::@3 to irq::@16 [phi:irq::@3->irq::@16] + // [19] phi from irq::@3 to irq::@16 [phi:irq::@3->irq::@16] __b16_from___b3: - // [18] phi irq::sin_col#2 = irq::sin_col#0 [phi:irq::@3->irq::@16#0] -- register_copy - // [18] phi irq::i#2 = 0 [phi:irq::@3->irq::@16#1] -- vbuxx=vbuc1 + // [19] phi irq::sin_col#2 = irq::sin_col#0 [phi:irq::@3->irq::@16#0] -- register_copy + // [19] phi irq::i#2 = 0 [phi:irq::@3->irq::@16#1] -- vbuxx=vbuc1 ldx #0 jmp __b16 // irq::@16 __b16: - // [19] if(irq::i#2<$28) goto irq::@17 -- vbuxx_lt_vbuc1_then_la1 + // [20] if(irq::i#2<$28) goto irq::@17 -- vbuxx_lt_vbuc1_then_la1 cpx #$28 bcc __b17 - // [20] phi from irq::@16 to irq::@18 [phi:irq::@16->irq::@18] + // [21] phi from irq::@16 to irq::@18 [phi:irq::@16->irq::@18] __b18_from___b16: - // [20] phi irq::l#2 = 0 [phi:irq::@16->irq::@18#0] -- vbuxx=vbuc1 + // [21] phi irq::l#2 = 0 [phi:irq::@16->irq::@18#0] -- vbuxx=vbuc1 ldx #0 jmp __b18 // Set all raster bars to black // irq::@18 __b18: - // [21] if(irq::l#2!=RASTER_LINES) goto irq::@19 -- vbuxx_neq_vbuc1_then_la1 + // [22] if(irq::l#2!=RASTER_LINES) goto irq::@19 -- vbuxx_neq_vbuc1_then_la1 cpx #RASTER_LINES bne __b19 jmp __b20 // irq::@20 __b20: - // [22] irq::sin_bar#0 = sin_idx -- vbuz1=vbuz2 + // [23] irq::sin_bar#0 = sin_idx -- vbuz1=vbuz2 // Big block of bars (16) lda.z sin_idx sta.z sin_bar - // [23] phi from irq::@20 to irq::@21 [phi:irq::@20->irq::@21] + // [24] phi from irq::@20 to irq::@21 [phi:irq::@20->irq::@21] __b21_from___b20: - // [23] phi irq::sin_bar#2 = irq::sin_bar#0 [phi:irq::@20->irq::@21#0] -- register_copy - // [23] phi irq::barcnt#2 = 0 [phi:irq::@20->irq::@21#1] -- vbuz1=vbuc1 + // [24] phi irq::sin_bar#2 = irq::sin_bar#0 [phi:irq::@20->irq::@21#0] -- register_copy + // [24] phi irq::barcnt#2 = 0 [phi:irq::@20->irq::@21#1] -- vbuz1=vbuc1 lda #0 sta.z barcnt jmp __b21 // irq::@21 __b21: - // [24] if(irq::barcnt#2<$10) goto irq::@22 -- vbuz1_lt_vbuc1_then_la1 + // [25] if(irq::barcnt#2<$10) goto irq::@22 -- vbuz1_lt_vbuc1_then_la1 lda.z barcnt cmp #$10 bcc __b22 - // [25] phi from irq::@21 to irq::@28 [phi:irq::@21->irq::@28] + // [26] phi from irq::@21 to irq::@28 [phi:irq::@21->irq::@28] __b28_from___b21: - // [25] phi irq::i3#2 = 0 [phi:irq::@21->irq::@28#0] -- vbuxx=vbuc1 + // [26] phi irq::i3#2 = 0 [phi:irq::@21->irq::@28#0] -- vbuxx=vbuc1 ldx #0 jmp __b28 // Produce dark area behind text // irq::@28 __b28: - // [26] if(irq::i3#2<$13) goto irq::@29 -- vbuxx_lt_vbuc1_then_la1 + // [27] if(irq::i3#2<$13) goto irq::@29 -- vbuxx_lt_vbuc1_then_la1 cpx #$13 bcc __b29 jmp __b30 // irq::@30 __b30: - // [27] irq::greet_offset#0 = greet_idx << 4 -- vbuyy=vbuz1_rol_4 + // [28] irq::greet_offset#0 = greet_idx << 4 -- vbuyy=vbuz1_rol_4 // Set up greetings lda.z greet_idx asl @@ -2306,81 +2314,81 @@ irq: { asl asl tay - // [28] phi from irq::@30 to irq::@31 [phi:irq::@30->irq::@31] + // [29] phi from irq::@30 to irq::@31 [phi:irq::@30->irq::@31] __b31_from___b30: - // [28] phi irq::greet_offset#2 = irq::greet_offset#0 [phi:irq::@30->irq::@31#0] -- register_copy - // [28] phi irq::i4#2 = 0 [phi:irq::@30->irq::@31#1] -- vbuxx=vbuc1 + // [29] phi irq::greet_offset#2 = irq::greet_offset#0 [phi:irq::@30->irq::@31#0] -- register_copy + // [29] phi irq::i4#2 = 0 [phi:irq::@30->irq::@31#1] -- vbuxx=vbuc1 ldx #0 jmp __b31 // irq::@31 __b31: - // [29] if(irq::i4#2<$10) goto irq::@32 -- vbuxx_lt_vbuc1_then_la1 + // [30] if(irq::i4#2<$10) goto irq::@32 -- vbuxx_lt_vbuc1_then_la1 cpx #$10 bcc __b32 jmp __b33 // irq::@33 __b33: - // [30] scroll_soft = -- scroll_soft -- vbuz1=_dec_vbuz1 + // [31] scroll_soft = -- scroll_soft -- vbuz1=_dec_vbuz1 dec.z scroll_soft - // [31] if(scroll_soft!=$ff) goto irq::@return -- vbuz1_neq_vbuc1_then_la1 + // [32] if(scroll_soft!=$ff) goto irq::@return -- vbuz1_neq_vbuc1_then_la1 lda #$ff cmp.z scroll_soft bne __breturn jmp __b34 // irq::@34 __b34: - // [32] scroll_soft = 7 -- vbuz1=vbuc1 + // [33] scroll_soft = 7 -- vbuz1=vbuc1 lda #7 sta.z scroll_soft - // [33] phi from irq::@34 to irq::@35 [phi:irq::@34->irq::@35] + // [34] phi from irq::@34 to irq::@35 [phi:irq::@34->irq::@35] __b35_from___b34: - // [33] phi irq::i5#2 = 0 [phi:irq::@34->irq::@35#0] -- vbuxx=vbuc1 + // [34] phi irq::i5#2 = 0 [phi:irq::@34->irq::@35#0] -- vbuxx=vbuc1 ldx #0 jmp __b35 // Move scroll on screen // irq::@35 __b35: - // [34] if(irq::i5#2<$27) goto irq::@36 -- vbuxx_lt_vbuc1_then_la1 + // [35] if(irq::i5#2<$27) goto irq::@36 -- vbuxx_lt_vbuc1_then_la1 cpx #$27 bcc __b36 jmp __b37 // irq::@37 __b37: - // [35] irq::nxt#0 = *scroll_ptr -- vbuaa=_deref_pbuz1 + // [36] irq::nxt#0 = *scroll_ptr -- vbuaa=_deref_pbuz1 // Show next char ldy #0 lda (scroll_ptr),y - // [36] scroll_ptr = ++ scroll_ptr -- pbuz1=_inc_pbuz1 + // [37] scroll_ptr = ++ scroll_ptr -- pbuz1=_inc_pbuz1 inw.z scroll_ptr - // [37] if(irq::nxt#0!=0) goto irq::@39 -- vbuaa_neq_0_then_la1 + // [38] if(irq::nxt#0!=0) goto irq::@39 -- vbuaa_neq_0_then_la1 cmp #0 bne __b39_from___b37 jmp __b38 // irq::@38 __b38: - // [38] scroll_ptr = SCROLL_TEXT -- pbuz1=pbuc1 + // [39] scroll_ptr = SCROLL_TEXT -- pbuz1=pbuc1 lda #SCROLL_TEXT sta.z scroll_ptr+1 - // [39] irq::nxt#1 = *scroll_ptr -- vbuaa=_deref_pbuz1 + // [40] irq::nxt#1 = *scroll_ptr -- vbuaa=_deref_pbuz1 ldy #0 lda (scroll_ptr),y - // [40] phi from irq::@37 irq::@38 to irq::@39 [phi:irq::@37/irq::@38->irq::@39] + // [41] phi from irq::@37 irq::@38 to irq::@39 [phi:irq::@37/irq::@38->irq::@39] __b39_from___b37: __b39_from___b38: - // [40] phi irq::nxt#2 = irq::nxt#0 [phi:irq::@37/irq::@38->irq::@39#0] -- register_copy + // [41] phi irq::nxt#2 = irq::nxt#0 [phi:irq::@37/irq::@38->irq::@39#0] -- register_copy jmp __b39 // irq::@39 __b39: - // [41] irq::$33 = irq::nxt#2 & $bf -- vbuaa=vbuaa_band_vbuc1 + // [42] irq::$33 = irq::nxt#2 & $bf -- vbuaa=vbuaa_band_vbuc1 and #$bf - // [42] *(DEFAULT_SCREEN+SCROLL_ROW*$28+$27) = irq::$33 -- _deref_pbuc1=vbuaa + // [43] *(DEFAULT_SCREEN+SCROLL_ROW*$28+$27) = irq::$33 -- _deref_pbuc1=vbuaa sta DEFAULT_SCREEN+SCROLL_ROW*$28+$27 jmp __breturn // irq::@return __breturn: - // [43] return + // [44] return // interrupt(isr_hardware_clobber_exit) -- isr_hardware_all_exit plz ply @@ -2389,244 +2397,244 @@ irq: { rti // irq::@36 __b36: - // [44] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [45] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda DEFAULT_SCREEN+SCROLL_ROW*$28+1,x sta DEFAULT_SCREEN+SCROLL_ROW*$28,x - // [45] irq::i5#1 = ++ irq::i5#2 -- vbuxx=_inc_vbuxx + // [46] irq::i5#1 = ++ irq::i5#2 -- vbuxx=_inc_vbuxx inx - // [33] phi from irq::@36 to irq::@35 [phi:irq::@36->irq::@35] + // [34] phi from irq::@36 to irq::@35 [phi:irq::@36->irq::@35] __b35_from___b36: - // [33] phi irq::i5#2 = irq::i5#1 [phi:irq::@36->irq::@35#0] -- register_copy + // [34] phi irq::i5#2 = irq::i5#1 [phi:irq::@36->irq::@35#0] -- register_copy jmp __b35 // irq::@32 __b32: - // [46] irq::$29 = GREETING[irq::greet_offset#2] & $bf -- vbuaa=pbuc1_derefidx_vbuyy_band_vbuc2 + // [47] irq::$29 = GREETING[irq::greet_offset#2] & $bf -- vbuaa=pbuc1_derefidx_vbuyy_band_vbuc2 lda #$bf and GREETING,y - // [47] (DEFAULT_SCREEN+GREET_ROW*$28+$d)[irq::i4#2] = irq::$29 -- pbuc1_derefidx_vbuxx=vbuaa + // [48] (DEFAULT_SCREEN+GREET_ROW*$28+$d)[irq::i4#2] = irq::$29 -- pbuc1_derefidx_vbuxx=vbuaa sta DEFAULT_SCREEN+GREET_ROW*$28+$d,x - // [48] irq::greet_offset#1 = ++ irq::greet_offset#2 -- vbuyy=_inc_vbuyy + // [49] irq::greet_offset#1 = ++ irq::greet_offset#2 -- vbuyy=_inc_vbuyy iny - // [49] irq::i4#1 = ++ irq::i4#2 -- vbuxx=_inc_vbuxx + // [50] irq::i4#1 = ++ irq::i4#2 -- vbuxx=_inc_vbuxx inx - // [28] phi from irq::@32 to irq::@31 [phi:irq::@32->irq::@31] + // [29] phi from irq::@32 to irq::@31 [phi:irq::@32->irq::@31] __b31_from___b32: - // [28] phi irq::greet_offset#2 = irq::greet_offset#1 [phi:irq::@32->irq::@31#0] -- register_copy - // [28] phi irq::i4#2 = irq::i4#1 [phi:irq::@32->irq::@31#1] -- register_copy + // [29] phi irq::greet_offset#2 = irq::greet_offset#1 [phi:irq::@32->irq::@31#0] -- register_copy + // [29] phi irq::i4#2 = irq::i4#1 [phi:irq::@32->irq::@31#1] -- register_copy jmp __b31 // irq::@29 __b29: - // [50] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 -- vbuaa=pbuc1_derefidx_vbuxx_ror_1 + // [51] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 -- vbuaa=pbuc1_derefidx_vbuxx_ror_1 lda rasters+SCROLL_Y,x lsr - // [51] irq::$27 = irq::$26 & 7 -- vbuaa=vbuaa_band_vbuc1 + // [52] irq::$27 = irq::$26 & 7 -- vbuaa=vbuaa_band_vbuc1 and #7 - // [52] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 -- pbuc1_derefidx_vbuxx=vbuaa + // [53] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 -- pbuc1_derefidx_vbuxx=vbuaa sta rasters+SCROLL_Y,x - // [53] irq::i3#1 = ++ irq::i3#2 -- vbuxx=_inc_vbuxx + // [54] irq::i3#1 = ++ irq::i3#2 -- vbuxx=_inc_vbuxx inx - // [25] phi from irq::@29 to irq::@28 [phi:irq::@29->irq::@28] + // [26] phi from irq::@29 to irq::@28 [phi:irq::@29->irq::@28] __b28_from___b29: - // [25] phi irq::i3#2 = irq::i3#1 [phi:irq::@29->irq::@28#0] -- register_copy + // [26] phi irq::i3#2 = irq::i3#1 [phi:irq::@29->irq::@28#0] -- register_copy jmp __b28 // irq::@22 __b22: - // [54] irq::idx#0 = SINE[irq::sin_bar#2] -- vbuxx=pbuc1_derefidx_vbuz1 + // [55] irq::idx#0 = SINE[irq::sin_bar#2] -- vbuxx=pbuc1_derefidx_vbuz1 ldy.z sin_bar ldx SINE,y - // [55] irq::barcol#0 = irq::barcnt#2 << 4 -- vbuzz=vbuz1_rol_4 + // [56] irq::barcol#0 = irq::barcnt#2 << 4 -- vbuzz=vbuz1_rol_4 lda.z barcnt asl asl asl asl taz - // [56] phi from irq::@22 to irq::@23 [phi:irq::@22->irq::@23] + // [57] phi from irq::@22 to irq::@23 [phi:irq::@22->irq::@23] __b23_from___b22: - // [56] phi irq::idx#3 = irq::idx#0 [phi:irq::@22->irq::@23#0] -- register_copy - // [56] phi irq::barcol#3 = irq::barcol#0 [phi:irq::@22->irq::@23#1] -- register_copy - // [56] phi irq::i1#2 = 0 [phi:irq::@22->irq::@23#2] -- vbuyy=vbuc1 + // [57] phi irq::idx#3 = irq::idx#0 [phi:irq::@22->irq::@23#0] -- register_copy + // [57] phi irq::barcol#3 = irq::barcol#0 [phi:irq::@22->irq::@23#1] -- register_copy + // [57] phi irq::i1#2 = 0 [phi:irq::@22->irq::@23#2] -- vbuyy=vbuc1 ldy #0 jmp __b23 // irq::@23 __b23: - // [57] if(irq::i1#2<$10) goto irq::@24 -- vbuyy_lt_vbuc1_then_la1 + // [58] if(irq::i1#2<$10) goto irq::@24 -- vbuyy_lt_vbuc1_then_la1 cpy #$10 bcc __b24 - // [58] phi from irq::@23 to irq::@25 [phi:irq::@23->irq::@25] + // [59] phi from irq::@23 to irq::@25 [phi:irq::@23->irq::@25] __b25_from___b23: - // [58] phi irq::idx#4 = irq::idx#3 [phi:irq::@23->irq::@25#0] -- register_copy - // [58] phi irq::barcol#4 = irq::barcol#3 [phi:irq::@23->irq::@25#1] -- register_copy - // [58] phi irq::i2#2 = 0 [phi:irq::@23->irq::@25#2] -- vbuyy=vbuc1 + // [59] phi irq::idx#4 = irq::idx#3 [phi:irq::@23->irq::@25#0] -- register_copy + // [59] phi irq::barcol#4 = irq::barcol#3 [phi:irq::@23->irq::@25#1] -- register_copy + // [59] phi irq::i2#2 = 0 [phi:irq::@23->irq::@25#2] -- vbuyy=vbuc1 ldy #0 jmp __b25 // irq::@25 __b25: - // [59] if(irq::i2#2<$f) goto irq::@26 -- vbuyy_lt_vbuc1_then_la1 + // [60] if(irq::i2#2<$f) goto irq::@26 -- vbuyy_lt_vbuc1_then_la1 cpy #$f bcc __b26 jmp __b27 // irq::@27 __b27: - // [60] irq::sin_bar#1 = irq::sin_bar#2 + $a -- vbuz1=vbuz1_plus_vbuc1 + // [61] irq::sin_bar#1 = irq::sin_bar#2 + $a -- vbuz1=vbuz1_plus_vbuc1 lda #$a clc adc.z sin_bar sta.z sin_bar - // [61] irq::barcnt#1 = ++ irq::barcnt#2 -- vbuz1=_inc_vbuz1 + // [62] irq::barcnt#1 = ++ irq::barcnt#2 -- vbuz1=_inc_vbuz1 inc.z barcnt - // [23] phi from irq::@27 to irq::@21 [phi:irq::@27->irq::@21] + // [24] phi from irq::@27 to irq::@21 [phi:irq::@27->irq::@21] __b21_from___b27: - // [23] phi irq::sin_bar#2 = irq::sin_bar#1 [phi:irq::@27->irq::@21#0] -- register_copy - // [23] phi irq::barcnt#2 = irq::barcnt#1 [phi:irq::@27->irq::@21#1] -- register_copy + // [24] phi irq::sin_bar#2 = irq::sin_bar#1 [phi:irq::@27->irq::@21#0] -- register_copy + // [24] phi irq::barcnt#2 = irq::barcnt#1 [phi:irq::@27->irq::@21#1] -- register_copy jmp __b21 // irq::@26 __b26: - // [62] irq::barcol#2 = -- irq::barcol#4 -- vbuzz=_dec_vbuzz + // [63] irq::barcol#2 = -- irq::barcol#4 -- vbuzz=_dec_vbuzz dez - // [63] rasters[irq::idx#4] = irq::barcol#2 -- pbuc1_derefidx_vbuxx=vbuzz + // [64] rasters[irq::idx#4] = irq::barcol#2 -- pbuc1_derefidx_vbuxx=vbuzz tza sta rasters,x - // [64] irq::idx#2 = ++ irq::idx#4 -- vbuxx=_inc_vbuxx + // [65] irq::idx#2 = ++ irq::idx#4 -- vbuxx=_inc_vbuxx inx - // [65] irq::i2#1 = ++ irq::i2#2 -- vbuyy=_inc_vbuyy + // [66] irq::i2#1 = ++ irq::i2#2 -- vbuyy=_inc_vbuyy iny - // [58] phi from irq::@26 to irq::@25 [phi:irq::@26->irq::@25] + // [59] phi from irq::@26 to irq::@25 [phi:irq::@26->irq::@25] __b25_from___b26: - // [58] phi irq::idx#4 = irq::idx#2 [phi:irq::@26->irq::@25#0] -- register_copy - // [58] phi irq::barcol#4 = irq::barcol#2 [phi:irq::@26->irq::@25#1] -- register_copy - // [58] phi irq::i2#2 = irq::i2#1 [phi:irq::@26->irq::@25#2] -- register_copy + // [59] phi irq::idx#4 = irq::idx#2 [phi:irq::@26->irq::@25#0] -- register_copy + // [59] phi irq::barcol#4 = irq::barcol#2 [phi:irq::@26->irq::@25#1] -- register_copy + // [59] phi irq::i2#2 = irq::i2#1 [phi:irq::@26->irq::@25#2] -- register_copy jmp __b25 // irq::@24 __b24: - // [66] rasters[irq::idx#3] = irq::barcol#3 -- pbuc1_derefidx_vbuxx=vbuzz + // [67] rasters[irq::idx#3] = irq::barcol#3 -- pbuc1_derefidx_vbuxx=vbuzz tza sta rasters,x - // [67] irq::idx#1 = ++ irq::idx#3 -- vbuxx=_inc_vbuxx + // [68] irq::idx#1 = ++ irq::idx#3 -- vbuxx=_inc_vbuxx inx - // [68] irq::barcol#1 = ++ irq::barcol#3 -- vbuzz=_inc_vbuzz + // [69] irq::barcol#1 = ++ irq::barcol#3 -- vbuzz=_inc_vbuzz inz - // [69] irq::i1#1 = ++ irq::i1#2 -- vbuyy=_inc_vbuyy + // [70] irq::i1#1 = ++ irq::i1#2 -- vbuyy=_inc_vbuyy iny - // [56] phi from irq::@24 to irq::@23 [phi:irq::@24->irq::@23] + // [57] phi from irq::@24 to irq::@23 [phi:irq::@24->irq::@23] __b23_from___b24: - // [56] phi irq::idx#3 = irq::idx#1 [phi:irq::@24->irq::@23#0] -- register_copy - // [56] phi irq::barcol#3 = irq::barcol#1 [phi:irq::@24->irq::@23#1] -- register_copy - // [56] phi irq::i1#2 = irq::i1#1 [phi:irq::@24->irq::@23#2] -- register_copy + // [57] phi irq::idx#3 = irq::idx#1 [phi:irq::@24->irq::@23#0] -- register_copy + // [57] phi irq::barcol#3 = irq::barcol#1 [phi:irq::@24->irq::@23#1] -- register_copy + // [57] phi irq::i1#2 = irq::i1#1 [phi:irq::@24->irq::@23#2] -- register_copy jmp __b23 // irq::@19 __b19: - // [70] rasters[irq::l#2] = 0 -- pbuc1_derefidx_vbuxx=vbuc2 + // [71] rasters[irq::l#2] = 0 -- pbuc1_derefidx_vbuxx=vbuc2 lda #0 sta rasters,x - // [71] irq::l#1 = ++ irq::l#2 -- vbuxx=_inc_vbuxx + // [72] irq::l#1 = ++ irq::l#2 -- vbuxx=_inc_vbuxx inx - // [20] phi from irq::@19 to irq::@18 [phi:irq::@19->irq::@18] + // [21] phi from irq::@19 to irq::@18 [phi:irq::@19->irq::@18] __b18_from___b19: - // [20] phi irq::l#2 = irq::l#1 [phi:irq::@19->irq::@18#0] -- register_copy + // [21] phi irq::l#2 = irq::l#1 [phi:irq::@19->irq::@18#0] -- register_copy jmp __b18 // irq::@17 __b17: - // [72] irq::col1#0 = SINE[irq::sin_col#2] >> 2 -- vbuaa=pbuc1_derefidx_vbuyy_ror_2 + // [73] irq::col1#0 = SINE[irq::sin_col#2] >> 2 -- vbuaa=pbuc1_derefidx_vbuyy_ror_2 // Greeting colors lda SINE,y lsr lsr - // [73] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 -- pbuc1_derefidx_vbuxx=vbuaa + // [74] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+GREET_ROW*$28,x - // [74] irq::col1#1 = irq::col1#0 >> 1 -- vbuaa=vbuaa_ror_1 + // [75] irq::col1#1 = irq::col1#0 >> 1 -- vbuaa=vbuaa_ror_1 // Logo colors lsr - // [75] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [76] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28-1,x - // [76] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [77] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+1*$28-2,x - // [77] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [78] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+2*$28-3,x - // [78] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [79] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+3*$28-4,x - // [79] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [80] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+4*$28-5,x - // [80] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [81] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+5*$28-6,x - // [81] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy + // [82] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy // Scroll colors lda PAL_GREEN,y sta COLORRAM+SCROLL_ROW*$28,x - // [82] irq::sin_col#1 = ++ irq::sin_col#2 -- vbuyy=_inc_vbuyy + // [83] irq::sin_col#1 = ++ irq::sin_col#2 -- vbuyy=_inc_vbuyy iny - // [83] irq::i#1 = ++ irq::i#2 -- vbuxx=_inc_vbuxx + // [84] irq::i#1 = ++ irq::i#2 -- vbuxx=_inc_vbuxx inx - // [18] phi from irq::@17 to irq::@16 [phi:irq::@17->irq::@16] + // [19] phi from irq::@17 to irq::@16 [phi:irq::@17->irq::@16] __b16_from___b17: - // [18] phi irq::sin_col#2 = irq::sin_col#1 [phi:irq::@17->irq::@16#0] -- register_copy - // [18] phi irq::i#2 = irq::i#1 [phi:irq::@17->irq::@16#1] -- register_copy + // [19] phi irq::sin_col#2 = irq::sin_col#1 [phi:irq::@17->irq::@16#0] -- register_copy + // [19] phi irq::i#2 = irq::i#1 [phi:irq::@17->irq::@16#1] -- register_copy jmp __b16 // irq::@2 __b2: - // [84] irq::col#0 = rasters[irq::line#10] -- vbuaa=pbuc1_derefidx_vbuzz + // [85] irq::col#0 = rasters[irq::line#10] -- vbuaa=pbuc1_derefidx_vbuzz tza tay lda rasters,y - // [85] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa + // [86] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR - // [86] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa + // [87] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR - // [87] if(irq::line#10 SCROLL_Y pos do zoom ldy.z greet_zoomx lda SINE,y - // [92] greet_zoomx = ++ greet_zoomx -- vbuz1=_inc_vbuz1 + // [93] greet_zoomx = ++ greet_zoomx -- vbuz1=_inc_vbuz1 inc.z greet_zoomx - // [93] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = irq::zoomval#0 -- _deref_pbuc1=vbuaa + // [94] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = irq::zoomval#0 -- _deref_pbuc1=vbuaa sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL - // [94] irq::$10 = irq::zoomval#0 + 1 -- vbuaa=vbuaa_plus_1 + // [95] irq::$10 = irq::zoomval#0 + 1 -- vbuaa=vbuaa_plus_1 inc - // [95] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = irq::$10 -- _deref_pbuc1=vbuaa + // [96] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = irq::$10 -- _deref_pbuc1=vbuaa sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO - // [96] if(greet_zoomx!=0) goto irq::@7 -- vbuz1_neq_0_then_la1 + // [97] if(greet_zoomx!=0) goto irq::@7 -- vbuz1_neq_0_then_la1 lda.z greet_zoomx bne __b7_from___b13 jmp __b14 // irq::@14 __b14: - // [97] greet_idx = ++ greet_idx -- vbuz1=_inc_vbuz1 + // [98] greet_idx = ++ greet_idx -- vbuz1=_inc_vbuz1 inc.z greet_idx - // [98] if(greet_idx!=GREET_COUNT) goto irq::@7 -- vbuz1_neq_vbuc1_then_la1 + // [99] if(greet_idx!=GREET_COUNT) goto irq::@7 -- vbuz1_neq_vbuc1_then_la1 lda #GREET_COUNT cmp.z greet_idx bne __b7_from___b14 jmp __b15 // irq::@15 __b15: - // [99] greet_idx = 0 -- vbuz1=vbuc1 + // [100] greet_idx = 0 -- vbuz1=vbuc1 lda #0 sta.z greet_idx - // [100] phi from irq::@12 irq::@13 irq::@14 irq::@15 irq::@4 irq::@5 irq::@6 to irq::@7 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7] + // [101] phi from irq::@12 irq::@13 irq::@14 irq::@15 irq::@4 irq::@5 irq::@6 to irq::@7 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7] __b7_from___b12: __b7_from___b13: __b7_from___b14: @@ -2634,23 +2642,23 @@ irq: { __b7_from___b4: __b7_from___b5: __b7_from___b6: - // [100] phi irq::wobble_idx#7 = irq::wobble_idx#10 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7#0] -- register_copy + // [101] phi irq::wobble_idx#7 = irq::wobble_idx#10 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7#0] -- register_copy jmp __b7 // irq::@7 __b7: - // [101] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 + // [102] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 // Wait for the next raster line lda VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER jmp __b8 // irq::@8 __b8: - // [102] if(irq::raster#0==*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)) goto irq::@8 -- vbuaa_eq__deref_pbuc1_then_la1 + // [103] if(irq::raster#0==*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)) goto irq::@8 -- vbuaa_eq__deref_pbuc1_then_la1 cmp VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER beq __b8 jmp __b9 // irq::@9 __b9: - // [103] irq::line#1 = ++ irq::line#10 -- vbuzz=_inc_vbuzz + // [104] irq::line#1 = ++ irq::line#10 -- vbuzz=_inc_vbuzz inz // [14] phi from irq::@9 to irq::@1 [phi:irq::@9->irq::@1] __b1_from___b9: @@ -2659,7 +2667,7 @@ irq: { jmp __b1 // irq::@6 __b6: - // [104] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 + // [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 // if raster position > SCROLL_Y pos do nozoom // default value lda #$50 @@ -2667,25 +2675,25 @@ irq: { jmp __b7_from___b6 // irq::@5 __b5: - // [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 + // [106] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 // if raster position = SCROLL_Y pos do scroll // no wobbling from this point lda #$50 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO - // [106] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft -- _deref_pbuc1=vbuz1 + // [107] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft -- _deref_pbuc1=vbuz1 // set softscroll lda.z scroll_soft sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2 jmp __b7_from___b5 // irq::@4 __b4: - // [107] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] -- _deref_pbuc1=pbuc2_derefidx_vbuxx + // [108] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] -- _deref_pbuc1=pbuc2_derefidx_vbuxx // if raster position < SCROLL_Y pos do wobble Logo! lda SINE,x sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO - // [108] irq::wobble_idx#1 = ++ irq::wobble_idx#10 -- vbuxx=_inc_vbuxx + // [109] irq::wobble_idx#1 = ++ irq::wobble_idx#10 -- vbuxx=_inc_vbuxx inx - // [109] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 -- _deref_pbuc1=vbuc2 + // [110] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 -- _deref_pbuc1=vbuc2 // No zooming lda #$66 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL @@ -2693,77 +2701,77 @@ irq: { } // main main: { - // [110] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 + // [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 // Enable MEGA65 features lda #$47 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY - // [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 + // [112] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 lda #$53 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY - // [112] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Enable 48MHz fast mode lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB - // [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [114] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC // asm { lda#0 } // Initialize music lda #0 - // [115] call *songInit + // [116] callexecute *songInit jsr songInit - // [116] call memset + // [117] call memset // Clear screen - // [142] phi from main to memset [phi:main->memset] + // [143] phi from main to memset [phi:main->memset] memset_from_main: jsr memset - // [117] phi from main to main::@1 [phi:main->main::@1] + // [118] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [117] phi main::i1#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + // [118] phi main::i1#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 ldx #0 jmp __b1 // Put MEGA logo on screen // main::@1 __b1: - // [118] if(main::i1#2<$bc*SIZEOF_BYTE) goto main::@2 -- vbuxx_lt_vbuc1_then_la1 + // [119] if(main::i1#2<$bc*SIZEOF_BYTE) goto main::@2 -- vbuxx_lt_vbuc1_then_la1 cpx #$bc*SIZEOF_BYTE bcc __b2 - // [119] phi from main::@1 to main::@3 [phi:main::@1->main::@3] + // [120] phi from main::@1 to main::@3 [phi:main::@1->main::@3] __b3_from___b1: - // [119] phi main::i2#2 = 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1 + // [120] phi main::i2#2 = 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1 ldx #0 jmp __b3 // Put '*' as default greeting // main::@3 __b3: - // [120] if(main::i2#2<$28) goto main::@4 -- vbuxx_lt_vbuc1_then_la1 + // [121] if(main::i2#2<$28) goto main::@4 -- vbuxx_lt_vbuc1_then_la1 cpx #$28 bcc __b4 - // [121] phi from main::@3 to main::@5 [phi:main::@3->main::@5] + // [122] phi from main::@3 to main::@5 [phi:main::@3->main::@5] __b5_from___b3: - // [121] phi main::i#2 = 0 [phi:main::@3->main::@5#0] -- vbuxx=vbuc1 + // [122] phi main::i#2 = 0 [phi:main::@3->main::@5#0] -- vbuxx=vbuc1 ldx #0 jmp __b5 - // [121] phi from main::@5 to main::@5 [phi:main::@5->main::@5] + // [122] phi from main::@5 to main::@5 [phi:main::@5->main::@5] __b5_from___b5: - // [121] phi main::i#2 = main::i#1 [phi:main::@5->main::@5#0] -- register_copy + // [122] phi main::i#2 = main::i#1 [phi:main::@5->main::@5#0] -- register_copy jmp __b5 // main::@5 __b5: - // [122] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [123] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda PAL_RED,x sta PALETTE_RED,x - // [123] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [124] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda PAL_GREEN,x sta PALETTE_GREEN,x - // [124] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [125] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda PAL_BLUE,x sta PALETTE_BLUE,x - // [125] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx + // [126] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx inx - // [126] if(main::i#1!=0) goto main::@5 -- vbuxx_neq_0_then_la1 + // [127] if(main::i#1!=0) goto main::@5 -- vbuxx_neq_0_then_la1 cpx #0 bne __b5_from___b5 jmp __b6 @@ -2772,43 +2780,43 @@ main: { // asm { sei } // Set up raster interrupts C64 style sei - // [128] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 + // [129] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT - // [129] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y -- _deref_pbuc1=vbuc2 + // [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y -- _deref_pbuc1=vbuc2 // Set raster line to 0x16 lda #IRQ_Y sta VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER - // [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 lda #$7f and VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 - // [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 + // [132] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE - // [132] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 + // [133] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 // Set the IRQ routine lda #irq sta HARDWARE_IRQ+1 - // [133] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 + // [134] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 // no kernal or BASIC rom visible lda #PROCPORT_DDR_MEMORY_MASK sta PROCPORT_DDR - // [134] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 + // [135] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 lda #PROCPORT_RAM_IO sta PROCPORT - // [135] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 + // [136] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 // open sideborder lda #1 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO // asm { cli } // Enable IRQ cli - // [137] phi from main::@6 main::@7 to main::@7 [phi:main::@6/main::@7->main::@7] + // [138] phi from main::@6 main::@7 to main::@7 [phi:main::@6/main::@7->main::@7] __b7_from___b6: __b7_from___b7: jmp __b7 @@ -2817,25 +2825,25 @@ main: { jmp __b7_from___b7 // main::@4 __b4: - // [138] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' -- pbuc1_derefidx_vbuxx=vbuc2 + // [139] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' -- pbuc1_derefidx_vbuxx=vbuc2 lda #'*' sta DEFAULT_SCREEN+GREET_ROW*$28,x - // [139] main::i2#1 = ++ main::i2#2 -- vbuxx=_inc_vbuxx + // [140] main::i2#1 = ++ main::i2#2 -- vbuxx=_inc_vbuxx inx - // [119] phi from main::@4 to main::@3 [phi:main::@4->main::@3] + // [120] phi from main::@4 to main::@3 [phi:main::@4->main::@3] __b3_from___b4: - // [119] phi main::i2#2 = main::i2#1 [phi:main::@4->main::@3#0] -- register_copy + // [120] phi main::i2#2 = main::i2#1 [phi:main::@4->main::@3#0] -- register_copy jmp __b3 // main::@2 __b2: - // [140] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [141] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda MEGA_LOGO,x sta DEFAULT_SCREEN+LOGO_ROW*$28,x - // [141] main::i1#1 = ++ main::i1#2 -- vbuxx=_inc_vbuxx + // [142] main::i1#1 = ++ main::i1#2 -- vbuxx=_inc_vbuxx inx - // [117] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [118] phi from main::@2 to main::@1 [phi:main::@2->main::@1] __b1_from___b2: - // [117] phi main::i1#2 = main::i1#1 [phi:main::@2->main::@1#0] -- register_copy + // [118] phi main::i1#2 = main::i1#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 } // memset @@ -2846,9 +2854,9 @@ memset: { .label str = DEFAULT_SCREEN .label end = str+num .label dst = 4 - // [143] phi from memset to memset::@1 [phi:memset->memset::@1] + // [144] phi from memset to memset::@1 [phi:memset->memset::@1] __b1_from_memset: - // [143] phi memset::dst#2 = (byte*)memset::str#0 [phi:memset->memset::@1#0] -- pbuz1=pbuc1 + // [144] phi memset::dst#2 = (byte*)memset::str#0 [phi:memset->memset::@1#0] -- pbuz1=pbuc1 lda #str @@ -2856,7 +2864,7 @@ memset: { jmp __b1 // memset::@1 __b1: - // [144] if(memset::dst#2!=memset::end#0) goto memset::@2 -- pbuz1_neq_pbuc1_then_la1 + // [145] if(memset::dst#2!=memset::end#0) goto memset::@2 -- pbuz1_neq_pbuc1_then_la1 lda.z dst+1 cmp #>end bne __b2 @@ -2866,19 +2874,19 @@ memset: { jmp __breturn // memset::@return __breturn: - // [145] return + // [146] return rts // memset::@2 __b2: - // [146] *memset::dst#2 = memset::c#0 -- _deref_pbuz1=vbuc1 + // [147] *memset::dst#2 = memset::c#0 -- _deref_pbuz1=vbuc1 lda #c ldy #0 sta (dst),y - // [147] memset::dst#1 = ++ memset::dst#2 -- pbuz1=_inc_pbuz1 + // [148] memset::dst#1 = ++ memset::dst#2 -- pbuz1=_inc_pbuz1 inw.z dst - // [143] phi from memset::@2 to memset::@1 [phi:memset::@2->memset::@1] + // [144] phi from memset::@2 to memset::@1 [phi:memset::@2->memset::@1] __b1_from___b2: - // [143] phi memset::dst#2 = memset::dst#1 [phi:memset::@2->memset::@1#0] -- register_copy + // [144] phi memset::dst#2 = memset::dst#1 [phi:memset::@2->memset::@1#0] -- register_copy jmp __b1 } // File Data @@ -2963,6 +2971,7 @@ Replacing label __b7_from___b4 with __b7 Replacing label __b5_from___b5 with __b5 Replacing label __b7_from___b7 with __b7 Removing instruction __b1_from___init1: +Removing instruction __b3_from___b1: Removing instruction __b39_from___b37: Removing instruction __b39_from___b38: Removing instruction __b7_from___b12: @@ -3184,9 +3193,9 @@ void* memset::return void* memset::str constant void* memset::str#0 str = (void*)DEFAULT_SCREEN constant byte* rasters[RASTER_LINES] = { fill( RASTER_LINES, 0) } -byte* volatile scroll_ptr loadstore zp[2]:8 0.1276595744680851 +byte* volatile scroll_ptr loadstore zp[2]:8 0.19672131147540986 volatile byte scroll_soft loadstore zp[1]:7 0.2441860465116279 -volatile byte sin_idx loadstore zp[1]:6 0.22641509433962262 +volatile byte sin_idx loadstore zp[1]:6 0.49999999999999994 constant void()* songInit = (void()*)SONG constant void()* songPlay = (void()*)SONG+3 @@ -3413,70 +3422,71 @@ irq: { beq !__b2+ jmp __b2 !__b2: + // [16] phi from irq::@1 to irq::@3 [phi:irq::@1->irq::@3] // irq::@3 // (*songPlay)() - // [16] call *songPlay + // [17] callexecute *songPlay // play music jsr songPlay // char sin_col = sin_idx - // [17] irq::sin_col#0 = sin_idx -- vbuyy=vbuz1 + // [18] irq::sin_col#0 = sin_idx -- vbuyy=vbuz1 // Set up colors behind logo, scroll and greets ldy.z sin_idx - // [18] phi from irq::@3 to irq::@16 [phi:irq::@3->irq::@16] - // [18] phi irq::sin_col#2 = irq::sin_col#0 [phi:irq::@3->irq::@16#0] -- register_copy - // [18] phi irq::i#2 = 0 [phi:irq::@3->irq::@16#1] -- vbuxx=vbuc1 + // [19] phi from irq::@3 to irq::@16 [phi:irq::@3->irq::@16] + // [19] phi irq::sin_col#2 = irq::sin_col#0 [phi:irq::@3->irq::@16#0] -- register_copy + // [19] phi irq::i#2 = 0 [phi:irq::@3->irq::@16#1] -- vbuxx=vbuc1 ldx #0 // irq::@16 __b16: // for(char i=0;i<40;i++) - // [19] if(irq::i#2<$28) goto irq::@17 -- vbuxx_lt_vbuc1_then_la1 + // [20] if(irq::i#2<$28) goto irq::@17 -- vbuxx_lt_vbuc1_then_la1 cpx #$28 bcs !__b17+ jmp __b17 !__b17: - // [20] phi from irq::@16 to irq::@18 [phi:irq::@16->irq::@18] - // [20] phi irq::l#2 = 0 [phi:irq::@16->irq::@18#0] -- vbuxx=vbuc1 + // [21] phi from irq::@16 to irq::@18 [phi:irq::@16->irq::@18] + // [21] phi irq::l#2 = 0 [phi:irq::@16->irq::@18#0] -- vbuxx=vbuc1 ldx #0 // Set all raster bars to black // irq::@18 __b18: // for(char l=0;l!=RASTER_LINES;l++) - // [21] if(irq::l#2!=RASTER_LINES) goto irq::@19 -- vbuxx_neq_vbuc1_then_la1 + // [22] if(irq::l#2!=RASTER_LINES) goto irq::@19 -- vbuxx_neq_vbuc1_then_la1 cpx #RASTER_LINES beq !__b19+ jmp __b19 !__b19: // irq::@20 // char sin_bar = sin_idx - // [22] irq::sin_bar#0 = sin_idx -- vbuz1=vbuz2 + // [23] irq::sin_bar#0 = sin_idx -- vbuz1=vbuz2 // Big block of bars (16) lda.z sin_idx sta.z sin_bar - // [23] phi from irq::@20 to irq::@21 [phi:irq::@20->irq::@21] - // [23] phi irq::sin_bar#2 = irq::sin_bar#0 [phi:irq::@20->irq::@21#0] -- register_copy - // [23] phi irq::barcnt#2 = 0 [phi:irq::@20->irq::@21#1] -- vbuz1=vbuc1 + // [24] phi from irq::@20 to irq::@21 [phi:irq::@20->irq::@21] + // [24] phi irq::sin_bar#2 = irq::sin_bar#0 [phi:irq::@20->irq::@21#0] -- register_copy + // [24] phi irq::barcnt#2 = 0 [phi:irq::@20->irq::@21#1] -- vbuz1=vbuc1 lda #0 sta.z barcnt // irq::@21 __b21: // for(char barcnt=0; barcnt<16; barcnt++) - // [24] if(irq::barcnt#2<$10) goto irq::@22 -- vbuz1_lt_vbuc1_then_la1 + // [25] if(irq::barcnt#2<$10) goto irq::@22 -- vbuz1_lt_vbuc1_then_la1 lda.z barcnt cmp #$10 bcc __b22 - // [25] phi from irq::@21 to irq::@28 [phi:irq::@21->irq::@28] - // [25] phi irq::i3#2 = 0 [phi:irq::@21->irq::@28#0] -- vbuxx=vbuc1 + // [26] phi from irq::@21 to irq::@28 [phi:irq::@21->irq::@28] + // [26] phi irq::i3#2 = 0 [phi:irq::@21->irq::@28#0] -- vbuxx=vbuc1 ldx #0 // Produce dark area behind text // irq::@28 __b28: // for(char i=0;i<19;i++) - // [26] if(irq::i3#2<$13) goto irq::@29 -- vbuxx_lt_vbuc1_then_la1 + // [27] if(irq::i3#2<$13) goto irq::@29 -- vbuxx_lt_vbuc1_then_la1 cpx #$13 bcc __b29 // irq::@30 // char greet_offset = greet_idx*16 - // [27] irq::greet_offset#0 = greet_idx << 4 -- vbuyy=vbuz1_rol_4 + // [28] irq::greet_offset#0 = greet_idx << 4 -- vbuyy=vbuz1_rol_4 // Set up greetings lda.z greet_idx asl @@ -3484,75 +3494,75 @@ irq: { asl asl tay - // [28] phi from irq::@30 to irq::@31 [phi:irq::@30->irq::@31] - // [28] phi irq::greet_offset#2 = irq::greet_offset#0 [phi:irq::@30->irq::@31#0] -- register_copy - // [28] phi irq::i4#2 = 0 [phi:irq::@30->irq::@31#1] -- vbuxx=vbuc1 + // [29] phi from irq::@30 to irq::@31 [phi:irq::@30->irq::@31] + // [29] phi irq::greet_offset#2 = irq::greet_offset#0 [phi:irq::@30->irq::@31#0] -- register_copy + // [29] phi irq::i4#2 = 0 [phi:irq::@30->irq::@31#1] -- vbuxx=vbuc1 ldx #0 // irq::@31 __b31: // for(char i=0;i<16;i++) - // [29] if(irq::i4#2<$10) goto irq::@32 -- vbuxx_lt_vbuc1_then_la1 + // [30] if(irq::i4#2<$10) goto irq::@32 -- vbuxx_lt_vbuc1_then_la1 cpx #$10 bcc __b32 // irq::@33 // if(--scroll_soft == 0xff) - // [30] scroll_soft = -- scroll_soft -- vbuz1=_dec_vbuz1 + // [31] scroll_soft = -- scroll_soft -- vbuz1=_dec_vbuz1 dec.z scroll_soft - // [31] if(scroll_soft!=$ff) goto irq::@return -- vbuz1_neq_vbuc1_then_la1 + // [32] if(scroll_soft!=$ff) goto irq::@return -- vbuz1_neq_vbuc1_then_la1 lda #$ff cmp.z scroll_soft bne __breturn // irq::@34 // scroll_soft = 7 - // [32] scroll_soft = 7 -- vbuz1=vbuc1 + // [33] scroll_soft = 7 -- vbuz1=vbuc1 lda #7 sta.z scroll_soft - // [33] phi from irq::@34 to irq::@35 [phi:irq::@34->irq::@35] - // [33] phi irq::i5#2 = 0 [phi:irq::@34->irq::@35#0] -- vbuxx=vbuc1 + // [34] phi from irq::@34 to irq::@35 [phi:irq::@34->irq::@35] + // [34] phi irq::i5#2 = 0 [phi:irq::@34->irq::@35#0] -- vbuxx=vbuc1 ldx #0 // Move scroll on screen // irq::@35 __b35: // for(char i=0;i<39;i++) - // [34] if(irq::i5#2<$27) goto irq::@36 -- vbuxx_lt_vbuc1_then_la1 + // [35] if(irq::i5#2<$27) goto irq::@36 -- vbuxx_lt_vbuc1_then_la1 cpx #$27 bcc __b36 // irq::@37 // char nxt = *(scroll_ptr++) - // [35] irq::nxt#0 = *scroll_ptr -- vbuaa=_deref_pbuz1 + // [36] irq::nxt#0 = *scroll_ptr -- vbuaa=_deref_pbuz1 // Show next char ldy #0 lda (scroll_ptr),y - // [36] scroll_ptr = ++ scroll_ptr -- pbuz1=_inc_pbuz1 + // [37] scroll_ptr = ++ scroll_ptr -- pbuz1=_inc_pbuz1 inw.z scroll_ptr // if(nxt == 0) - // [37] if(irq::nxt#0!=0) goto irq::@39 -- vbuaa_neq_0_then_la1 + // [38] if(irq::nxt#0!=0) goto irq::@39 -- vbuaa_neq_0_then_la1 cmp #0 bne __b39 // irq::@38 // scroll_ptr = SCROLL_TEXT - // [38] scroll_ptr = SCROLL_TEXT -- pbuz1=pbuc1 + // [39] scroll_ptr = SCROLL_TEXT -- pbuz1=pbuc1 lda #SCROLL_TEXT sta.z scroll_ptr+1 // nxt = *scroll_ptr - // [39] irq::nxt#1 = *scroll_ptr -- vbuaa=_deref_pbuz1 + // [40] irq::nxt#1 = *scroll_ptr -- vbuaa=_deref_pbuz1 lda (scroll_ptr),y - // [40] phi from irq::@37 irq::@38 to irq::@39 [phi:irq::@37/irq::@38->irq::@39] - // [40] phi irq::nxt#2 = irq::nxt#0 [phi:irq::@37/irq::@38->irq::@39#0] -- register_copy + // [41] phi from irq::@37 irq::@38 to irq::@39 [phi:irq::@37/irq::@38->irq::@39] + // [41] phi irq::nxt#2 = irq::nxt#0 [phi:irq::@37/irq::@38->irq::@39#0] -- register_copy // irq::@39 __b39: // nxt & 0xbf - // [41] irq::$33 = irq::nxt#2 & $bf -- vbuaa=vbuaa_band_vbuc1 + // [42] irq::$33 = irq::nxt#2 & $bf -- vbuaa=vbuaa_band_vbuc1 and #$bf // *(SCREEN + SCROLL_ROW*40 + 39) = nxt & 0xbf - // [42] *(DEFAULT_SCREEN+SCROLL_ROW*$28+$27) = irq::$33 -- _deref_pbuc1=vbuaa + // [43] *(DEFAULT_SCREEN+SCROLL_ROW*$28+$27) = irq::$33 -- _deref_pbuc1=vbuaa sta DEFAULT_SCREEN+SCROLL_ROW*$28+$27 // irq::@return __breturn: // } - // [43] return + // [44] return // interrupt(isr_hardware_clobber_exit) -- isr_hardware_all_exit plz ply @@ -3562,284 +3572,284 @@ irq: { // irq::@36 __b36: // (SCREEN + SCROLL_ROW*40)[i] = (SCREEN + SCROLL_ROW*40 + 1)[i] - // [44] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [45] (DEFAULT_SCREEN+SCROLL_ROW*$28)[irq::i5#2] = (DEFAULT_SCREEN+SCROLL_ROW*$28+1)[irq::i5#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda DEFAULT_SCREEN+SCROLL_ROW*$28+1,x sta DEFAULT_SCREEN+SCROLL_ROW*$28,x // for(char i=0;i<39;i++) - // [45] irq::i5#1 = ++ irq::i5#2 -- vbuxx=_inc_vbuxx + // [46] irq::i5#1 = ++ irq::i5#2 -- vbuxx=_inc_vbuxx inx - // [33] phi from irq::@36 to irq::@35 [phi:irq::@36->irq::@35] - // [33] phi irq::i5#2 = irq::i5#1 [phi:irq::@36->irq::@35#0] -- register_copy + // [34] phi from irq::@36 to irq::@35 [phi:irq::@36->irq::@35] + // [34] phi irq::i5#2 = irq::i5#1 [phi:irq::@36->irq::@35#0] -- register_copy jmp __b35 // irq::@32 __b32: // GREETING[greet_offset++] & 0xbf - // [46] irq::$29 = GREETING[irq::greet_offset#2] & $bf -- vbuaa=pbuc1_derefidx_vbuyy_band_vbuc2 + // [47] irq::$29 = GREETING[irq::greet_offset#2] & $bf -- vbuaa=pbuc1_derefidx_vbuyy_band_vbuc2 lda #$bf and GREETING,y // (SCREEN + GREET_ROW*40 + 13)[i] = GREETING[greet_offset++] & 0xbf - // [47] (DEFAULT_SCREEN+GREET_ROW*$28+$d)[irq::i4#2] = irq::$29 -- pbuc1_derefidx_vbuxx=vbuaa + // [48] (DEFAULT_SCREEN+GREET_ROW*$28+$d)[irq::i4#2] = irq::$29 -- pbuc1_derefidx_vbuxx=vbuaa sta DEFAULT_SCREEN+GREET_ROW*$28+$d,x // (SCREEN + GREET_ROW*40 + 13)[i] = GREETING[greet_offset++] & 0xbf; - // [48] irq::greet_offset#1 = ++ irq::greet_offset#2 -- vbuyy=_inc_vbuyy + // [49] irq::greet_offset#1 = ++ irq::greet_offset#2 -- vbuyy=_inc_vbuyy iny // for(char i=0;i<16;i++) - // [49] irq::i4#1 = ++ irq::i4#2 -- vbuxx=_inc_vbuxx + // [50] irq::i4#1 = ++ irq::i4#2 -- vbuxx=_inc_vbuxx inx - // [28] phi from irq::@32 to irq::@31 [phi:irq::@32->irq::@31] - // [28] phi irq::greet_offset#2 = irq::greet_offset#1 [phi:irq::@32->irq::@31#0] -- register_copy - // [28] phi irq::i4#2 = irq::i4#1 [phi:irq::@32->irq::@31#1] -- register_copy + // [29] phi from irq::@32 to irq::@31 [phi:irq::@32->irq::@31] + // [29] phi irq::greet_offset#2 = irq::greet_offset#1 [phi:irq::@32->irq::@31#0] -- register_copy + // [29] phi irq::i4#2 = irq::i4#1 [phi:irq::@32->irq::@31#1] -- register_copy jmp __b31 // irq::@29 __b29: // rasters[SCROLL_Y+i] /2 - // [50] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 -- vbuaa=pbuc1_derefidx_vbuxx_ror_1 + // [51] irq::$26 = (rasters+SCROLL_Y)[irq::i3#2] >> 1 -- vbuaa=pbuc1_derefidx_vbuxx_ror_1 lda rasters+SCROLL_Y,x lsr // rasters[SCROLL_Y+i] /2 & 7 - // [51] irq::$27 = irq::$26 & 7 -- vbuaa=vbuaa_band_vbuc1 + // [52] irq::$27 = irq::$26 & 7 -- vbuaa=vbuaa_band_vbuc1 and #7 // rasters[SCROLL_Y+i] = rasters[SCROLL_Y+i] /2 & 7 - // [52] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 -- pbuc1_derefidx_vbuxx=vbuaa + // [53] (rasters+SCROLL_Y)[irq::i3#2] = irq::$27 -- pbuc1_derefidx_vbuxx=vbuaa sta rasters+SCROLL_Y,x // for(char i=0;i<19;i++) - // [53] irq::i3#1 = ++ irq::i3#2 -- vbuxx=_inc_vbuxx + // [54] irq::i3#1 = ++ irq::i3#2 -- vbuxx=_inc_vbuxx inx - // [25] phi from irq::@29 to irq::@28 [phi:irq::@29->irq::@28] - // [25] phi irq::i3#2 = irq::i3#1 [phi:irq::@29->irq::@28#0] -- register_copy + // [26] phi from irq::@29 to irq::@28 [phi:irq::@29->irq::@28] + // [26] phi irq::i3#2 = irq::i3#1 [phi:irq::@29->irq::@28#0] -- register_copy jmp __b28 // irq::@22 __b22: // char idx = SINE[sin_bar] - // [54] irq::idx#0 = SINE[irq::sin_bar#2] -- vbuxx=pbuc1_derefidx_vbuz1 + // [55] irq::idx#0 = SINE[irq::sin_bar#2] -- vbuxx=pbuc1_derefidx_vbuz1 ldy.z sin_bar ldx SINE,y // char barcol = barcnt*16 - // [55] irq::barcol#0 = irq::barcnt#2 << 4 -- vbuzz=vbuz1_rol_4 + // [56] irq::barcol#0 = irq::barcnt#2 << 4 -- vbuzz=vbuz1_rol_4 lda.z barcnt asl asl asl asl taz - // [56] phi from irq::@22 to irq::@23 [phi:irq::@22->irq::@23] - // [56] phi irq::idx#3 = irq::idx#0 [phi:irq::@22->irq::@23#0] -- register_copy - // [56] phi irq::barcol#3 = irq::barcol#0 [phi:irq::@22->irq::@23#1] -- register_copy - // [56] phi irq::i1#2 = 0 [phi:irq::@22->irq::@23#2] -- vbuyy=vbuc1 + // [57] phi from irq::@22 to irq::@23 [phi:irq::@22->irq::@23] + // [57] phi irq::idx#3 = irq::idx#0 [phi:irq::@22->irq::@23#0] -- register_copy + // [57] phi irq::barcol#3 = irq::barcol#0 [phi:irq::@22->irq::@23#1] -- register_copy + // [57] phi irq::i1#2 = 0 [phi:irq::@22->irq::@23#2] -- vbuyy=vbuc1 ldy #0 // irq::@23 __b23: // for(char i=0;i<16;i++) - // [57] if(irq::i1#2<$10) goto irq::@24 -- vbuyy_lt_vbuc1_then_la1 + // [58] if(irq::i1#2<$10) goto irq::@24 -- vbuyy_lt_vbuc1_then_la1 cpy #$10 bcc __b24 - // [58] phi from irq::@23 to irq::@25 [phi:irq::@23->irq::@25] - // [58] phi irq::idx#4 = irq::idx#3 [phi:irq::@23->irq::@25#0] -- register_copy - // [58] phi irq::barcol#4 = irq::barcol#3 [phi:irq::@23->irq::@25#1] -- register_copy - // [58] phi irq::i2#2 = 0 [phi:irq::@23->irq::@25#2] -- vbuyy=vbuc1 + // [59] phi from irq::@23 to irq::@25 [phi:irq::@23->irq::@25] + // [59] phi irq::idx#4 = irq::idx#3 [phi:irq::@23->irq::@25#0] -- register_copy + // [59] phi irq::barcol#4 = irq::barcol#3 [phi:irq::@23->irq::@25#1] -- register_copy + // [59] phi irq::i2#2 = 0 [phi:irq::@23->irq::@25#2] -- vbuyy=vbuc1 ldy #0 // irq::@25 __b25: // for(char i=0;i<15;i++) - // [59] if(irq::i2#2<$f) goto irq::@26 -- vbuyy_lt_vbuc1_then_la1 + // [60] if(irq::i2#2<$f) goto irq::@26 -- vbuyy_lt_vbuc1_then_la1 cpy #$f bcc __b26 // irq::@27 // sin_bar += 10 - // [60] irq::sin_bar#1 = irq::sin_bar#2 + $a -- vbuz1=vbuz1_plus_vbuc1 + // [61] irq::sin_bar#1 = irq::sin_bar#2 + $a -- vbuz1=vbuz1_plus_vbuc1 lda #$a clc adc.z sin_bar sta.z sin_bar // for(char barcnt=0; barcnt<16; barcnt++) - // [61] irq::barcnt#1 = ++ irq::barcnt#2 -- vbuz1=_inc_vbuz1 + // [62] irq::barcnt#1 = ++ irq::barcnt#2 -- vbuz1=_inc_vbuz1 inc.z barcnt - // [23] phi from irq::@27 to irq::@21 [phi:irq::@27->irq::@21] - // [23] phi irq::sin_bar#2 = irq::sin_bar#1 [phi:irq::@27->irq::@21#0] -- register_copy - // [23] phi irq::barcnt#2 = irq::barcnt#1 [phi:irq::@27->irq::@21#1] -- register_copy + // [24] phi from irq::@27 to irq::@21 [phi:irq::@27->irq::@21] + // [24] phi irq::sin_bar#2 = irq::sin_bar#1 [phi:irq::@27->irq::@21#0] -- register_copy + // [24] phi irq::barcnt#2 = irq::barcnt#1 [phi:irq::@27->irq::@21#1] -- register_copy jmp __b21 // irq::@26 __b26: // rasters[idx++] = --barcol; - // [62] irq::barcol#2 = -- irq::barcol#4 -- vbuzz=_dec_vbuzz + // [63] irq::barcol#2 = -- irq::barcol#4 -- vbuzz=_dec_vbuzz dez // rasters[idx++] = --barcol - // [63] rasters[irq::idx#4] = irq::barcol#2 -- pbuc1_derefidx_vbuxx=vbuzz + // [64] rasters[irq::idx#4] = irq::barcol#2 -- pbuc1_derefidx_vbuxx=vbuzz tza sta rasters,x // rasters[idx++] = --barcol; - // [64] irq::idx#2 = ++ irq::idx#4 -- vbuxx=_inc_vbuxx + // [65] irq::idx#2 = ++ irq::idx#4 -- vbuxx=_inc_vbuxx inx // for(char i=0;i<15;i++) - // [65] irq::i2#1 = ++ irq::i2#2 -- vbuyy=_inc_vbuyy + // [66] irq::i2#1 = ++ irq::i2#2 -- vbuyy=_inc_vbuyy iny - // [58] phi from irq::@26 to irq::@25 [phi:irq::@26->irq::@25] - // [58] phi irq::idx#4 = irq::idx#2 [phi:irq::@26->irq::@25#0] -- register_copy - // [58] phi irq::barcol#4 = irq::barcol#2 [phi:irq::@26->irq::@25#1] -- register_copy - // [58] phi irq::i2#2 = irq::i2#1 [phi:irq::@26->irq::@25#2] -- register_copy + // [59] phi from irq::@26 to irq::@25 [phi:irq::@26->irq::@25] + // [59] phi irq::idx#4 = irq::idx#2 [phi:irq::@26->irq::@25#0] -- register_copy + // [59] phi irq::barcol#4 = irq::barcol#2 [phi:irq::@26->irq::@25#1] -- register_copy + // [59] phi irq::i2#2 = irq::i2#1 [phi:irq::@26->irq::@25#2] -- register_copy jmp __b25 // irq::@24 __b24: // rasters[idx++] = barcol++ - // [66] rasters[irq::idx#3] = irq::barcol#3 -- pbuc1_derefidx_vbuxx=vbuzz + // [67] rasters[irq::idx#3] = irq::barcol#3 -- pbuc1_derefidx_vbuxx=vbuzz tza sta rasters,x // rasters[idx++] = barcol++; - // [67] irq::idx#1 = ++ irq::idx#3 -- vbuxx=_inc_vbuxx + // [68] irq::idx#1 = ++ irq::idx#3 -- vbuxx=_inc_vbuxx inx - // [68] irq::barcol#1 = ++ irq::barcol#3 -- vbuzz=_inc_vbuzz + // [69] irq::barcol#1 = ++ irq::barcol#3 -- vbuzz=_inc_vbuzz inz // for(char i=0;i<16;i++) - // [69] irq::i1#1 = ++ irq::i1#2 -- vbuyy=_inc_vbuyy + // [70] irq::i1#1 = ++ irq::i1#2 -- vbuyy=_inc_vbuyy iny - // [56] phi from irq::@24 to irq::@23 [phi:irq::@24->irq::@23] - // [56] phi irq::idx#3 = irq::idx#1 [phi:irq::@24->irq::@23#0] -- register_copy - // [56] phi irq::barcol#3 = irq::barcol#1 [phi:irq::@24->irq::@23#1] -- register_copy - // [56] phi irq::i1#2 = irq::i1#1 [phi:irq::@24->irq::@23#2] -- register_copy + // [57] phi from irq::@24 to irq::@23 [phi:irq::@24->irq::@23] + // [57] phi irq::idx#3 = irq::idx#1 [phi:irq::@24->irq::@23#0] -- register_copy + // [57] phi irq::barcol#3 = irq::barcol#1 [phi:irq::@24->irq::@23#1] -- register_copy + // [57] phi irq::i1#2 = irq::i1#1 [phi:irq::@24->irq::@23#2] -- register_copy jmp __b23 // irq::@19 __b19: // rasters[l] = 0 - // [70] rasters[irq::l#2] = 0 -- pbuc1_derefidx_vbuxx=vbuc2 + // [71] rasters[irq::l#2] = 0 -- pbuc1_derefidx_vbuxx=vbuc2 lda #0 sta rasters,x // for(char l=0;l!=RASTER_LINES;l++) - // [71] irq::l#1 = ++ irq::l#2 -- vbuxx=_inc_vbuxx + // [72] irq::l#1 = ++ irq::l#2 -- vbuxx=_inc_vbuxx inx - // [20] phi from irq::@19 to irq::@18 [phi:irq::@19->irq::@18] - // [20] phi irq::l#2 = irq::l#1 [phi:irq::@19->irq::@18#0] -- register_copy + // [21] phi from irq::@19 to irq::@18 [phi:irq::@19->irq::@18] + // [21] phi irq::l#2 = irq::l#1 [phi:irq::@19->irq::@18#0] -- register_copy jmp __b18 // irq::@17 __b17: // char col = SINE[sin_col]/4 - // [72] irq::col1#0 = SINE[irq::sin_col#2] >> 2 -- vbuaa=pbuc1_derefidx_vbuyy_ror_2 + // [73] irq::col1#0 = SINE[irq::sin_col#2] >> 2 -- vbuaa=pbuc1_derefidx_vbuyy_ror_2 // Greeting colors lda SINE,y lsr lsr // (COLORRAM + GREET_ROW*40)[i] = col - // [73] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 -- pbuc1_derefidx_vbuxx=vbuaa + // [74] (COLORRAM+GREET_ROW*$28)[irq::i#2] = irq::col1#0 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+GREET_ROW*$28,x // col /= 2 - // [74] irq::col1#1 = irq::col1#0 >> 1 -- vbuaa=vbuaa_ror_1 + // [75] irq::col1#1 = irq::col1#0 >> 1 -- vbuaa=vbuaa_ror_1 // Logo colors lsr // (COLORRAM + LOGO_ROW*40 + 0*40 - 1)[i] = col - // [75] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [76] (COLORRAM+LOGO_ROW*$28-1)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28-1,x // (COLORRAM + LOGO_ROW*40 + 1*40 - 2)[i] = col - // [76] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [77] (COLORRAM+LOGO_ROW*$28+1*$28-2)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+1*$28-2,x // (COLORRAM + LOGO_ROW*40 + 2*40 - 3)[i] = col - // [77] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [78] (COLORRAM+LOGO_ROW*$28+2*$28-3)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+2*$28-3,x // (COLORRAM + LOGO_ROW*40 + 3*40 - 4)[i] = col - // [78] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [79] (COLORRAM+LOGO_ROW*$28+3*$28-4)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+3*$28-4,x // (COLORRAM + LOGO_ROW*40 + 4*40 - 5)[i] = col - // [79] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [80] (COLORRAM+LOGO_ROW*$28+4*$28-5)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+4*$28-5,x // (COLORRAM + LOGO_ROW*40 + 5*40 - 6)[i] = col - // [80] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa + // [81] (COLORRAM+LOGO_ROW*$28+5*$28-6)[irq::i#2] = irq::col1#1 -- pbuc1_derefidx_vbuxx=vbuaa sta COLORRAM+LOGO_ROW*$28+5*$28-6,x // (COLORRAM + SCROLL_ROW*40)[i] = PAL_GREEN[sin_col] - // [81] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy + // [82] (COLORRAM+SCROLL_ROW*$28)[irq::i#2] = PAL_GREEN[irq::sin_col#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy // Scroll colors lda PAL_GREEN,y sta COLORRAM+SCROLL_ROW*$28,x // sin_col++; - // [82] irq::sin_col#1 = ++ irq::sin_col#2 -- vbuyy=_inc_vbuyy + // [83] irq::sin_col#1 = ++ irq::sin_col#2 -- vbuyy=_inc_vbuyy iny // for(char i=0;i<40;i++) - // [83] irq::i#1 = ++ irq::i#2 -- vbuxx=_inc_vbuxx + // [84] irq::i#1 = ++ irq::i#2 -- vbuxx=_inc_vbuxx inx - // [18] phi from irq::@17 to irq::@16 [phi:irq::@17->irq::@16] - // [18] phi irq::sin_col#2 = irq::sin_col#1 [phi:irq::@17->irq::@16#0] -- register_copy - // [18] phi irq::i#2 = irq::i#1 [phi:irq::@17->irq::@16#1] -- register_copy + // [19] phi from irq::@17 to irq::@16 [phi:irq::@17->irq::@16] + // [19] phi irq::sin_col#2 = irq::sin_col#1 [phi:irq::@17->irq::@16#0] -- register_copy + // [19] phi irq::i#2 = irq::i#1 [phi:irq::@17->irq::@16#1] -- register_copy jmp __b16 // irq::@2 __b2: // char col = rasters[line] - // [84] irq::col#0 = rasters[irq::line#10] -- vbuaa=pbuc1_derefidx_vbuzz + // [85] irq::col#0 = rasters[irq::line#10] -- vbuaa=pbuc1_derefidx_vbuzz tza tay lda rasters,y // VICIII->BORDER_COLOR = col - // [85] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa + // [86] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_BORDER_COLOR // VICIII->BG_COLOR = col - // [86] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa + // [87] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR) = irq::col#0 -- _deref_pbuc1=vbuaa sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_BG_COLOR // if(line < SCROLL_Y) - // [87] if(irq::line#10 SCROLL_Y pos do zoom ldy.z greet_zoomx lda SINE,y - // [92] greet_zoomx = ++ greet_zoomx -- vbuz1=_inc_vbuz1 + // [93] greet_zoomx = ++ greet_zoomx -- vbuz1=_inc_vbuz1 inc.z greet_zoomx // VICIV->CHRXSCL = zoomval - // [93] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = irq::zoomval#0 -- _deref_pbuc1=vbuaa + // [94] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = irq::zoomval#0 -- _deref_pbuc1=vbuaa sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL // zoomval+1 - // [94] irq::$10 = irq::zoomval#0 + 1 -- vbuaa=vbuaa_plus_1 + // [95] irq::$10 = irq::zoomval#0 + 1 -- vbuaa=vbuaa_plus_1 inc // VICIV->TEXTXPOS_LO = zoomval+1 - // [95] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = irq::$10 -- _deref_pbuc1=vbuaa + // [96] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = irq::$10 -- _deref_pbuc1=vbuaa sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO // if(greet_zoomx==0) - // [96] if(greet_zoomx!=0) goto irq::@7 -- vbuz1_neq_0_then_la1 + // [97] if(greet_zoomx!=0) goto irq::@7 -- vbuz1_neq_0_then_la1 lda.z greet_zoomx bne __b7 // irq::@14 // if(++greet_idx == GREET_COUNT) - // [97] greet_idx = ++ greet_idx -- vbuz1=_inc_vbuz1 + // [98] greet_idx = ++ greet_idx -- vbuz1=_inc_vbuz1 inc.z greet_idx - // [98] if(greet_idx!=GREET_COUNT) goto irq::@7 -- vbuz1_neq_vbuc1_then_la1 + // [99] if(greet_idx!=GREET_COUNT) goto irq::@7 -- vbuz1_neq_vbuc1_then_la1 lda #GREET_COUNT cmp.z greet_idx bne __b7 // irq::@15 // greet_idx = 0 - // [99] greet_idx = 0 -- vbuz1=vbuc1 + // [100] greet_idx = 0 -- vbuz1=vbuc1 lda #0 sta.z greet_idx - // [100] phi from irq::@12 irq::@13 irq::@14 irq::@15 irq::@4 irq::@5 irq::@6 to irq::@7 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7] - // [100] phi irq::wobble_idx#7 = irq::wobble_idx#10 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7#0] -- register_copy + // [101] phi from irq::@12 irq::@13 irq::@14 irq::@15 irq::@4 irq::@5 irq::@6 to irq::@7 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7] + // [101] phi irq::wobble_idx#7 = irq::wobble_idx#10 [phi:irq::@12/irq::@13/irq::@14/irq::@15/irq::@4/irq::@5/irq::@6->irq::@7#0] -- register_copy // irq::@7 __b7: // char raster = VICII->RASTER - // [101] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 + // [102] irq::raster#0 = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) -- vbuaa=_deref_pbuc1 // Wait for the next raster line lda VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER // irq::@8 __b8: // while(raster == VICII->RASTER) - // [102] if(irq::raster#0==*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)) goto irq::@8 -- vbuaa_eq__deref_pbuc1_then_la1 + // [103] if(irq::raster#0==*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)) goto irq::@8 -- vbuaa_eq__deref_pbuc1_then_la1 cmp VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER beq __b8 // irq::@9 // for(char line=0;line!=RASTER_LINES;line++) - // [103] irq::line#1 = ++ irq::line#10 -- vbuzz=_inc_vbuzz + // [104] irq::line#1 = ++ irq::line#10 -- vbuzz=_inc_vbuzz inz // [14] phi from irq::@9 to irq::@1 [phi:irq::@9->irq::@1] // [14] phi irq::wobble_idx#10 = irq::wobble_idx#7 [phi:irq::@9->irq::@1#0] -- register_copy @@ -3848,7 +3858,7 @@ irq: { // irq::@6 __b6: // VICIV->TEXTXPOS_LO = 0x50 - // [104] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 + // [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 // if raster position > SCROLL_Y pos do nozoom // default value lda #$50 @@ -3856,13 +3866,13 @@ irq: { jmp __b7 // irq::@5 __b5: - // [105] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 + // [106] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $50 -- _deref_pbuc1=vbuc2 // if raster position = SCROLL_Y pos do scroll // no wobbling from this point lda #$50 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO // VICII->CONTROL2 = scroll_soft - // [106] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft -- _deref_pbuc1=vbuz1 + // [107] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2) = scroll_soft -- _deref_pbuc1=vbuz1 // set softscroll lda.z scroll_soft sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL2 @@ -3870,15 +3880,15 @@ irq: { // irq::@4 __b4: // VICIV->TEXTXPOS_LO = SINE[wobble_idx++] - // [107] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] -- _deref_pbuc1=pbuc2_derefidx_vbuxx + // [108] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = SINE[irq::wobble_idx#10] -- _deref_pbuc1=pbuc2_derefidx_vbuxx // if raster position < SCROLL_Y pos do wobble Logo! lda SINE,x sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO // VICIV->TEXTXPOS_LO = SINE[wobble_idx++]; - // [108] irq::wobble_idx#1 = ++ irq::wobble_idx#10 -- vbuxx=_inc_vbuxx + // [109] irq::wobble_idx#1 = ++ irq::wobble_idx#10 -- vbuxx=_inc_vbuxx inx // VICIV->CHRXSCL = 0x66 - // [109] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 -- _deref_pbuc1=vbuc2 + // [110] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL) = $66 -- _deref_pbuc1=vbuc2 // No zooming lda #$66 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRXSCL @@ -3887,22 +3897,22 @@ irq: { // main main: { // VICIII->KEY = 0x47 - // [110] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 + // [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $47 -- _deref_pbuc1=vbuc2 // Enable MEGA65 features lda #$47 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY // VICIII->KEY = 0x53 - // [111] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 + // [112] *((byte*)VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY) = $53 -- _deref_pbuc1=vbuc2 lda #$53 sta VICIII+OFFSET_STRUCT_MOS4569_VICIII_KEY // VICIV->CONTROLB |= 0x40 - // [112] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Enable 48MHz fast mode lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB // VICIV->CONTROLC |= 0x40 - // [113] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [114] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 lda #$40 ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC @@ -3911,56 +3921,56 @@ main: { // Initialize music lda #0 // (*songInit)() - // [115] call *songInit + // [116] callexecute *songInit jsr songInit // memset(SCREEN, ' ', 40*25) - // [116] call memset + // [117] call memset // Clear screen - // [142] phi from main to memset [phi:main->memset] + // [143] phi from main to memset [phi:main->memset] jsr memset - // [117] phi from main to main::@1 [phi:main->main::@1] - // [117] phi main::i1#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + // [118] phi from main to main::@1 [phi:main->main::@1] + // [118] phi main::i1#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 ldx #0 // Put MEGA logo on screen // main::@1 __b1: // for( char i=0; imain::@3] - // [119] phi main::i2#2 = 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1 + // [120] phi from main::@1 to main::@3 [phi:main::@1->main::@3] + // [120] phi main::i2#2 = 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1 ldx #0 // Put '*' as default greeting // main::@3 __b3: // for( char i=0;i<40;i++) - // [120] if(main::i2#2<$28) goto main::@4 -- vbuxx_lt_vbuc1_then_la1 + // [121] if(main::i2#2<$28) goto main::@4 -- vbuxx_lt_vbuc1_then_la1 cpx #$28 bcc __b4 - // [121] phi from main::@3 to main::@5 [phi:main::@3->main::@5] - // [121] phi main::i#2 = 0 [phi:main::@3->main::@5#0] -- vbuxx=vbuc1 + // [122] phi from main::@3 to main::@5 [phi:main::@3->main::@5] + // [122] phi main::i#2 = 0 [phi:main::@3->main::@5#0] -- vbuxx=vbuc1 ldx #0 - // [121] phi from main::@5 to main::@5 [phi:main::@5->main::@5] - // [121] phi main::i#2 = main::i#1 [phi:main::@5->main::@5#0] -- register_copy + // [122] phi from main::@5 to main::@5 [phi:main::@5->main::@5] + // [122] phi main::i#2 = main::i#1 [phi:main::@5->main::@5#0] -- register_copy // main::@5 __b5: // PALETTE_RED[i] = PAL_RED[i] - // [122] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [123] PALETTE_RED[main::i#2] = PAL_RED[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda PAL_RED,x sta PALETTE_RED,x // PALETTE_GREEN[i] = PAL_GREEN[i] - // [123] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [124] PALETTE_GREEN[main::i#2] = PAL_GREEN[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda PAL_GREEN,x sta PALETTE_GREEN,x // PALETTE_BLUE[i] = PAL_BLUE[i] - // [124] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [125] PALETTE_BLUE[main::i#2] = PAL_BLUE[main::i#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda PAL_BLUE,x sta PALETTE_BLUE,x // while(++i!=0) - // [125] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx + // [126] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx inx - // [126] if(main::i#1!=0) goto main::@5 -- vbuxx_neq_0_then_la1 + // [127] if(main::i#1!=0) goto main::@5 -- vbuxx_neq_0_then_la1 cpx #0 bne __b5 // main::@6 @@ -3969,43 +3979,43 @@ main: { // Set up raster interrupts C64 style sei // CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR - // [128] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 + // [129] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR -- _deref_pbuc1=vbuc2 // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT // VICII->RASTER = IRQ_Y - // [129] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y -- _deref_pbuc1=vbuc2 + // [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER) = IRQ_Y -- _deref_pbuc1=vbuc2 // Set raster line to 0x16 lda #IRQ_Y sta VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER // VICII->CONTROL1 &= 0x7f - // [130] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1) & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 lda #$7f and VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1 // VICII->IRQ_ENABLE = IRQ_RASTER - // [131] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 + // [132] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE) = IRQ_RASTER -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE // *HARDWARE_IRQ = &irq - // [132] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 + // [133] *HARDWARE_IRQ = &irq -- _deref_qprc1=pprc2 // Set the IRQ routine lda #irq sta HARDWARE_IRQ+1 // *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK - // [133] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 + // [134] *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK -- _deref_pbuc1=vbuc2 // no kernal or BASIC rom visible lda #PROCPORT_DDR_MEMORY_MASK sta PROCPORT_DDR // *PROCPORT = PROCPORT_RAM_IO - // [134] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 + // [135] *PROCPORT = PROCPORT_RAM_IO -- _deref_pbuc1=vbuc2 lda #PROCPORT_RAM_IO sta PROCPORT // VICIV->SIDBDRWD_LO = 1 - // [135] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 + // [136] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 1 -- _deref_pbuc1=vbuc2 // open sideborder lda #1 sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO @@ -4013,33 +4023,33 @@ main: { // asm { cli } // Enable IRQ cli - // [137] phi from main::@6 main::@7 to main::@7 [phi:main::@6/main::@7->main::@7] + // [138] phi from main::@6 main::@7 to main::@7 [phi:main::@6/main::@7->main::@7] // main::@7 __b7: jmp __b7 // main::@4 __b4: // (SCREEN + GREET_ROW*40)[i] = '*' - // [138] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' -- pbuc1_derefidx_vbuxx=vbuc2 + // [139] (DEFAULT_SCREEN+GREET_ROW*$28)[main::i2#2] = '*' -- pbuc1_derefidx_vbuxx=vbuc2 lda #'*' sta DEFAULT_SCREEN+GREET_ROW*$28,x // for( char i=0;i<40;i++) - // [139] main::i2#1 = ++ main::i2#2 -- vbuxx=_inc_vbuxx + // [140] main::i2#1 = ++ main::i2#2 -- vbuxx=_inc_vbuxx inx - // [119] phi from main::@4 to main::@3 [phi:main::@4->main::@3] - // [119] phi main::i2#2 = main::i2#1 [phi:main::@4->main::@3#0] -- register_copy + // [120] phi from main::@4 to main::@3 [phi:main::@4->main::@3] + // [120] phi main::i2#2 = main::i2#1 [phi:main::@4->main::@3#0] -- register_copy jmp __b3 // main::@2 __b2: // (SCREEN + LOGO_ROW*40)[i] = MEGA_LOGO[i] - // [140] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx + // [141] (DEFAULT_SCREEN+LOGO_ROW*$28)[main::i1#2] = MEGA_LOGO[main::i1#2] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx lda MEGA_LOGO,x sta DEFAULT_SCREEN+LOGO_ROW*$28,x // for( char i=0; imain::@1] - // [117] phi main::i1#2 = main::i1#1 [phi:main::@2->main::@1#0] -- register_copy + // [118] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [118] phi main::i1#2 = main::i1#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 } // memset @@ -4050,8 +4060,8 @@ memset: { .label str = DEFAULT_SCREEN .label end = str+num .label dst = 4 - // [143] phi from memset to memset::@1 [phi:memset->memset::@1] - // [143] phi memset::dst#2 = (byte*)memset::str#0 [phi:memset->memset::@1#0] -- pbuz1=pbuc1 + // [144] phi from memset to memset::@1 [phi:memset->memset::@1] + // [144] phi memset::dst#2 = (byte*)memset::str#0 [phi:memset->memset::@1#0] -- pbuz1=pbuc1 lda #str @@ -4059,7 +4069,7 @@ memset: { // memset::@1 __b1: // for(char* dst = str; dst!=end; dst++) - // [144] if(memset::dst#2!=memset::end#0) goto memset::@2 -- pbuz1_neq_pbuc1_then_la1 + // [145] if(memset::dst#2!=memset::end#0) goto memset::@2 -- pbuz1_neq_pbuc1_then_la1 lda.z dst+1 cmp #>end bne __b2 @@ -4068,20 +4078,20 @@ memset: { bne __b2 // memset::@return // } - // [145] return + // [146] return rts // memset::@2 __b2: // *dst = c - // [146] *memset::dst#2 = memset::c#0 -- _deref_pbuz1=vbuc1 + // [147] *memset::dst#2 = memset::c#0 -- _deref_pbuz1=vbuc1 lda #c ldy #0 sta (dst),y // for(char* dst = str; dst!=end; dst++) - // [147] memset::dst#1 = ++ memset::dst#2 -- pbuz1=_inc_pbuz1 + // [148] memset::dst#1 = ++ memset::dst#2 -- pbuz1=_inc_pbuz1 inw.z dst - // [143] phi from memset::@2 to memset::@1 [phi:memset::@2->memset::@1] - // [143] phi memset::dst#2 = memset::dst#1 [phi:memset::@2->memset::@1#0] -- register_copy + // [144] phi from memset::@2 to memset::@1 [phi:memset::@2->memset::@1] + // [144] phi memset::dst#2 = memset::dst#1 [phi:memset::@2->memset::@1#0] -- register_copy jmp __b1 } // File Data diff --git a/src/test/ref/examples/mega65/raster65.sym b/src/test/ref/examples/mega65/raster65.sym index 8cf8ff521..bd5797cb5 100644 --- a/src/test/ref/examples/mega65/raster65.sym +++ b/src/test/ref/examples/mega65/raster65.sym @@ -150,9 +150,9 @@ void* memset::return void* memset::str constant void* memset::str#0 str = (void*)DEFAULT_SCREEN constant byte* rasters[RASTER_LINES] = { fill( RASTER_LINES, 0) } -byte* volatile scroll_ptr loadstore zp[2]:8 0.1276595744680851 +byte* volatile scroll_ptr loadstore zp[2]:8 0.19672131147540986 volatile byte scroll_soft loadstore zp[1]:7 0.2441860465116279 -volatile byte sin_idx loadstore zp[1]:6 0.22641509433962262 +volatile byte sin_idx loadstore zp[1]:6 0.49999999999999994 constant void()* songInit = (void()*)SONG constant void()* songPlay = (void()*)SONG+3 diff --git a/src/test/ref/examples/rom/rom.asm b/src/test/ref/examples/rom/rom.asm index 53a9fac63..6863fbcdf 100644 --- a/src/test/ref/examples/rom/rom.asm +++ b/src/test/ref/examples/rom/rom.asm @@ -70,7 +70,7 @@ main: { call1: { .const OFFSET_STACK_PARAM1 = 1 .const OFFSET_STACK_PARAM2 = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label param1 = 2 tsx lda STACK_BASE+OFFSET_STACK_PARAM1,x @@ -82,7 +82,7 @@ call1: { adc.z param1 // } tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x rts } // A memory based ROM function that will transfer all parameters and return values through zeropage. diff --git a/src/test/ref/examples/rom/rom.cfg b/src/test/ref/examples/rom/rom.cfg index 54298c8ce..aa81d8e70 100644 --- a/src/test/ref/examples/rom/rom.cfg +++ b/src/test/ref/examples/rom/rom.cfg @@ -49,7 +49,7 @@ call1: scope:[call1] from [31] call1::return#0 = call1::param1#0 + call1::param2#0 to:call1::@return call1::@return: scope:[call1] from call1 - [32] stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#0 + [32] stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#0 [33] return to:@return diff --git a/src/test/ref/examples/rom/rom.log b/src/test/ref/examples/rom/rom.log index e22116167..ac470d4c7 100644 --- a/src/test/ref/examples/rom/rom.log +++ b/src/test/ref/examples/rom/rom.log @@ -5,7 +5,7 @@ Calling convention __stackcall adding prepare/execute/finalize for main::$0 = ca Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call call1 3 4 Calling convention STACK_CALL replacing param(call1::param1) with stackidx(byte,call1::OFFSET_STACK_PARAM1) Calling convention STACK_CALL replacing param(call1::param2) with stackidx(byte,call1::OFFSET_STACK_PARAM2) -Calling convention STACK_CALL adding stack return stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return +Calling convention STACK_CALL adding stack return stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(byte) Calling convention STACK_CALL adding stack pull main::$1 = stackpull(byte) Calling convention STACK_CALL adding stack push stackpush(byte) = 1 @@ -24,7 +24,7 @@ call1: scope:[call1] from to:call1::@return call1::@return: scope:[call1] from call1 call1::return#1 = phi( call1/call1::return#0 ) - stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#1 + stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#1 return to:@return @@ -122,7 +122,7 @@ __stackcall byte call1(byte call1::param1 , byte call1::param2) byte~ call1::$0 constant byte call1::OFFSET_STACK_PARAM1 = 1 constant byte call1::OFFSET_STACK_PARAM2 = 0 -constant byte call1::OFFSET_STACK_RETURN = 1 +constant byte call1::OFFSET_STACK_RETURN_1 = 1 byte call1::param1 byte call1::param1#0 byte call1::param2 @@ -325,7 +325,7 @@ call1: scope:[call1] from [31] call1::return#0 = call1::param1#0 + call1::param2#0 to:call1::@return call1::@return: scope:[call1] from call1 - [32] stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#0 + [32] stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#0 [33] return to:@return @@ -453,7 +453,7 @@ Statement [30] call1::param2#0 = stackidx(byte,call1::OFFSET_STACK_PARAM2) [ cal Removing always clobbered register reg byte a as potential for zp[1]:15 [ call1::param1#0 ] Removing always clobbered register reg byte x as potential for zp[1]:15 [ call1::param1#0 ] Statement [31] call1::return#0 = call1::param1#0 + call1::param2#0 [ call1::return#0 ] ( call1:2 [ call1::return#0 ] { } call1:8 [ call1::return#0 ] { } ) always clobbers reg byte a -Statement [32] stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#0 [ ] ( call1:2 [ ] { } call1:8 [ ] { } ) always clobbers reg byte x +Statement [32] stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#0 [ ] ( call1:2 [ ] { } call1:8 [ ] { } ) always clobbers reg byte x Statement [35] call2::$0 = call2::param1#2 + call2::param2#2 [ call2::$0 ] ( call2:12 [ call2::$0 ] { { call2::return = } } call2:16 [ call2::$0 ] { { call2::return = } } ) always clobbers reg byte a Statement [39] call3::return#0 = call3::param1#2 + call3::param2#2 [ call3::return#0 ] ( call3:20 [ call3::return#0 ] { { call3::return#0 = call3::return#2 } } call3:24 [ call3::return#0 ] { { call3::return#0 = call3::return#3 } } ) always clobbers reg byte a Statement [0] stackpush(byte) = 1 [ ] ( [ ] { { call2::return = } } ) always clobbers reg byte a @@ -467,7 +467,7 @@ Statement [10] main::$1 = stackpull(byte) [ main::$1 ] ( [ main::$1 ] { { call2 Statement [29] call1::param1#0 = stackidx(byte,call1::OFFSET_STACK_PARAM1) [ call1::param1#0 ] ( call1:2 [ call1::param1#0 ] { } call1:8 [ call1::param1#0 ] { } ) always clobbers reg byte a reg byte x Statement [30] call1::param2#0 = stackidx(byte,call1::OFFSET_STACK_PARAM2) [ call1::param1#0 call1::param2#0 ] ( call1:2 [ call1::param1#0 call1::param2#0 ] { } call1:8 [ call1::param1#0 call1::param2#0 ] { } ) always clobbers reg byte a reg byte x Statement [31] call1::return#0 = call1::param1#0 + call1::param2#0 [ call1::return#0 ] ( call1:2 [ call1::return#0 ] { } call1:8 [ call1::return#0 ] { } ) always clobbers reg byte a -Statement [32] stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#0 [ ] ( call1:2 [ ] { } call1:8 [ ] { } ) always clobbers reg byte x +Statement [32] stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#0 [ ] ( call1:2 [ ] { } call1:8 [ ] { } ) always clobbers reg byte x Statement [35] call2::$0 = call2::param1#2 + call2::param2#2 [ call2::$0 ] ( call2:12 [ call2::$0 ] { { call2::return = } } call2:16 [ call2::$0 ] { { call2::return = } } ) always clobbers reg byte a Statement [39] call3::return#0 = call3::param1#2 + call3::param2#2 [ call3::return#0 ] ( call3:20 [ call3::return#0 ] { { call3::return#0 = call3::return#2 } } call3:24 [ call3::return#0 ] { { call3::return#0 = call3::return#3 } } ) always clobbers reg byte a Potential registers zp[1]:2 [ call2::param1#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , @@ -637,7 +637,7 @@ main: { call1: { .const OFFSET_STACK_PARAM1 = 1 .const OFFSET_STACK_PARAM2 = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label param1 = 2 // [29] call1::param1#0 = stackidx(byte,call1::OFFSET_STACK_PARAM1) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -652,9 +652,9 @@ call1: { jmp __breturn // call1::@return __breturn: - // [32] stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [32] stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [33] return rts } @@ -720,7 +720,7 @@ constant word STACK_BASE = $103 __stackcall byte call1(byte call1::param1 , byte call1::param2) constant byte call1::OFFSET_STACK_PARAM1 = 1 constant byte call1::OFFSET_STACK_PARAM2 = 0 -constant byte call1::OFFSET_STACK_RETURN = 1 +constant byte call1::OFFSET_STACK_RETURN_1 = 1 byte call1::param1 byte call1::param1#0 param1 zp[1]:2 11.0 byte call1::param2 @@ -897,7 +897,7 @@ main: { call1: { .const OFFSET_STACK_PARAM1 = 1 .const OFFSET_STACK_PARAM2 = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label param1 = 2 // [29] call1::param1#0 = stackidx(byte,call1::OFFSET_STACK_PARAM1) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -912,9 +912,9 @@ call1: { adc.z param1 // call1::@return // } - // [32] stackidx(byte,call1::OFFSET_STACK_RETURN) = call1::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [32] stackidx(byte,call1::OFFSET_STACK_RETURN_1) = call1::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [33] return rts } diff --git a/src/test/ref/examples/rom/rom.sym b/src/test/ref/examples/rom/rom.sym index a2738ff23..b92661e8f 100644 --- a/src/test/ref/examples/rom/rom.sym +++ b/src/test/ref/examples/rom/rom.sym @@ -2,7 +2,7 @@ constant word STACK_BASE = $103 __stackcall byte call1(byte call1::param1 , byte call1::param2) constant byte call1::OFFSET_STACK_PARAM1 = 1 constant byte call1::OFFSET_STACK_PARAM2 = 0 -constant byte call1::OFFSET_STACK_RETURN = 1 +constant byte call1::OFFSET_STACK_RETURN_1 = 1 byte call1::param1 byte call1::param1#0 param1 zp[1]:2 11.0 byte call1::param2 diff --git a/src/test/ref/function-pointer-noarg-call-10.cfg b/src/test/ref/function-pointer-noarg-call-10.cfg index 48cf0ba84..1dcb3b6c4 100644 --- a/src/test/ref/function-pointer-noarg-call-10.cfg +++ b/src/test/ref/function-pointer-noarg-call-10.cfg @@ -66,7 +66,7 @@ do10: scope:[do10] from main main::@1 to:do10::@1 do10::@1: scope:[do10] from do10 do10::@1 [24] do10::i#2 = phi( do10/0, do10::@1/do10::i#1 ) - [25] call *do10::fn#3 + [25] callexecute *do10::fn#3 [26] do10::i#1 = ++ do10::i#2 [27] if(do10::i#1!=$a) goto do10::@1 to:do10::@return diff --git a/src/test/ref/function-pointer-noarg-call-10.log b/src/test/ref/function-pointer-noarg-call-10.log index c5e5e257a..8c0e881b2 100644 --- a/src/test/ref/function-pointer-noarg-call-10.log +++ b/src/test/ref/function-pointer-noarg-call-10.log @@ -1,4 +1,5 @@ Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *do10::fn CONTROL FLOW GRAPH SSA @@ -10,7 +11,7 @@ do10: scope:[do10] from main main::@1 do10::@1: scope:[do10] from do10 do10::@1 do10::i#2 = phi( do10/do10::i#0, do10::@1/do10::i#1 ) do10::fn#2 = phi( do10/do10::fn#3, do10::@1/do10::fn#2 ) - call *do10::fn#2 + callexecute *do10::fn#2 do10::i#1 = do10::i#2 + rangenext(0,9) do10::$1 = do10::i#1 != rangelast(0,9) if(do10::$1) goto do10::@1 @@ -179,6 +180,7 @@ Calls in [__start] to main:3 Calls in [world] to print:7 Calls in [hello] to print:11 Calls in [main] to do10:15 do10:17 +Calls in [do10] to null:30 Created 4 initial phi equivalence classes Coalesced [27] print::i#3 = print::i#1 @@ -266,7 +268,7 @@ do10: scope:[do10] from main main::@1 to:do10::@1 do10::@1: scope:[do10] from do10 do10::@1 [24] do10::i#2 = phi( do10/0, do10::@1/do10::i#1 ) - [25] call *do10::fn#3 + [25] callexecute *do10::fn#3 [26] do10::i#1 = ++ do10::i#2 [27] if(do10::i#1!=$a) goto do10::@1 to:do10::@return @@ -282,7 +284,7 @@ void()* do10::fn void()* do10::fn#3 byte do10::i byte do10::i#1 1501.5 -byte do10::i#2 1001.0 +byte do10::i#2 2002.0 void hello() volatile byte idx loadstore 38.125 void main() @@ -317,16 +319,16 @@ Statement [18] SCREEN[idx] = print::msg#3[print::i#2] [ idx print::msg#3 print:: Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::i#2 print::i#1 ] Removing always clobbered register reg byte x as potential for zp[1]:4 [ print::i#2 print::i#1 ] Statement [21] if(0!=print::msg#3[print::i#1]) goto print::@1 [ idx print::msg#3 print::i#1 ] ( print:6 [ idx print::msg#3 print::i#1 ] { } print:9 [ idx print::msg#3 print::i#1 ] { } ) always clobbers reg byte a -Statement [25] call *do10::fn#3 [ do10::fn#3 do10::i#2 ] ( main:3::do10:12 [ do10::fn#3 do10::i#2 ] { } main:3::do10:14 [ do10::fn#3 do10::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [25] callexecute *do10::fn#3 [ do10::i#2 ] ( main:3::do10:12 [ do10::i#2 ] { } main:3::do10:14 [ do10::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte a as potential for zp[1]:7 [ do10::i#2 do10::i#1 ] Removing always clobbered register reg byte x as potential for zp[1]:7 [ do10::i#2 do10::i#1 ] Removing always clobbered register reg byte y as potential for zp[1]:7 [ do10::i#2 do10::i#1 ] -Statement [27] if(do10::i#1!=$a) goto do10::@1 [ do10::fn#3 do10::i#1 ] ( main:3::do10:12 [ do10::fn#3 do10::i#1 ] { } main:3::do10:14 [ do10::fn#3 do10::i#1 ] { } ) always clobbers reg byte a +Statement [27] if(do10::i#1!=$a) goto do10::@1 [ do10::i#1 ] ( main:3::do10:12 [ do10::i#1 ] { } main:3::do10:14 [ do10::i#1 ] { } ) always clobbers reg byte a Statement [1] idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a Statement [18] SCREEN[idx] = print::msg#3[print::i#2] [ idx print::msg#3 print::i#2 ] ( print:6 [ idx print::msg#3 print::i#2 ] { } print:9 [ idx print::msg#3 print::i#2 ] { } ) always clobbers reg byte a reg byte x Statement [21] if(0!=print::msg#3[print::i#1]) goto print::@1 [ idx print::msg#3 print::i#1 ] ( print:6 [ idx print::msg#3 print::i#1 ] { } print:9 [ idx print::msg#3 print::i#1 ] { } ) always clobbers reg byte a -Statement [25] call *do10::fn#3 [ do10::fn#3 do10::i#2 ] ( main:3::do10:12 [ do10::fn#3 do10::i#2 ] { } main:3::do10:14 [ do10::fn#3 do10::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y -Statement [27] if(do10::i#1!=$a) goto do10::@1 [ do10::fn#3 do10::i#1 ] ( main:3::do10:12 [ do10::fn#3 do10::i#1 ] { } main:3::do10:14 [ do10::fn#3 do10::i#1 ] { } ) always clobbers reg byte a +Statement [25] callexecute *do10::fn#3 [ do10::i#2 ] ( main:3::do10:12 [ do10::i#2 ] { } main:3::do10:14 [ do10::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [27] if(do10::i#1!=$a) goto do10::@1 [ do10::i#1 ] ( main:3::do10:12 [ do10::i#1 ] { } main:3::do10:14 [ do10::i#1 ] { } ) always clobbers reg byte a Potential registers zp[2]:2 [ print::msg#3 ] : zp[2]:2 , Potential registers zp[1]:4 [ print::i#2 print::i#1 ] : zp[1]:4 , reg byte y , Potential registers zp[2]:5 [ do10::fn#3 ] : zp[2]:5 , @@ -334,7 +336,7 @@ Potential registers zp[1]:7 [ do10::i#2 do10::i#1 ] : zp[1]:7 , Potential registers zp[1]:8 [ idx ] : zp[1]:8 , REGISTER UPLIFT SCOPES -Uplift Scope [do10] 2,502.5: zp[1]:7 [ do10::i#2 do10::i#1 ] 0: zp[2]:5 [ do10::fn#3 ] +Uplift Scope [do10] 3,503.5: zp[1]:7 [ do10::i#2 do10::i#1 ] 0: zp[2]:5 [ do10::fn#3 ] Uplift Scope [print] 252.5: zp[1]:4 [ print::i#2 print::i#1 ] 33.67: zp[2]:2 [ print::msg#3 ] Uplift Scope [] 38.12: zp[1]:8 [ idx ] Uplift Scope [hello] @@ -519,7 +521,7 @@ do10: { jmp __b1 // do10::@1 __b1: - // [25] call *do10::fn#3 + // [25] callexecute *do10::fn#3 jsr bi_fn // [26] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 inc.z i @@ -586,7 +588,7 @@ void()* do10::fn void()* do10::fn#3 fn zp[2]:4 byte do10::i byte do10::i#1 i zp[1]:6 1501.5 -byte do10::i#2 i zp[1]:6 1001.0 +byte do10::i#2 i zp[1]:6 2002.0 void hello() constant byte* hello::msg[7] = "hello " volatile byte idx loadstore zp[1]:7 38.125 @@ -753,7 +755,7 @@ do10: { // do10::@1 __b1: // (*fn)() - // [25] call *do10::fn#3 + // [25] callexecute *do10::fn#3 jsr bi_fn // for( byte i: 0..9) // [26] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 diff --git a/src/test/ref/function-pointer-noarg-call-10.sym b/src/test/ref/function-pointer-noarg-call-10.sym index 0bdc3d065..d88f25766 100644 --- a/src/test/ref/function-pointer-noarg-call-10.sym +++ b/src/test/ref/function-pointer-noarg-call-10.sym @@ -5,7 +5,7 @@ void()* do10::fn void()* do10::fn#3 fn zp[2]:4 byte do10::i byte do10::i#1 i zp[1]:6 1501.5 -byte do10::i#2 i zp[1]:6 1001.0 +byte do10::i#2 i zp[1]:6 2002.0 void hello() constant byte* hello::msg[7] = "hello " volatile byte idx loadstore zp[1]:7 38.125 diff --git a/src/test/ref/function-pointer-noarg-call-11.cfg b/src/test/ref/function-pointer-noarg-call-11.cfg index 85032159c..9074ff9dc 100644 --- a/src/test/ref/function-pointer-noarg-call-11.cfg +++ b/src/test/ref/function-pointer-noarg-call-11.cfg @@ -2,8 +2,8 @@ void main() main: scope:[main] from [0] phi() - [1] call myFunc - [2] call myFunc2 + [1] callexecute myFunc + [2] callexecute myFunc2 to:main::@return main::@return: scope:[main] from main [3] return diff --git a/src/test/ref/function-pointer-noarg-call-11.log b/src/test/ref/function-pointer-noarg-call-11.log index 4d2572d9e..3f071467a 100644 --- a/src/test/ref/function-pointer-noarg-call-11.log +++ b/src/test/ref/function-pointer-noarg-call-11.log @@ -1,4 +1,6 @@ Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *funcPointer +Calling convention STACK_CALL adding prepare/execute/finalize for call *funcPointer CONTROL FLOW GRAPH SSA @@ -21,9 +23,9 @@ myFunc2::@return: scope:[myFunc2] from myFunc2 void main() main: scope:[main] from __start::@1 funcPointer#0 = &myFunc - call *funcPointer#0 + callexecute *funcPointer#0 funcPointer#1 = &myFunc2 - call *funcPointer#1 + callexecute *funcPointer#1 to:main::@return main::@return: scope:[main] from main funcPointer#6 = phi( main/funcPointer#1 ) @@ -83,8 +85,8 @@ Constant funcPointer#0 = &myFunc Constant funcPointer#1 = &myFunc2 Constant funcPointer#3 = (void()*) 0 Successful SSA optimization Pass2ConstantIdentification -Replacing constant pointer function [5] call myFunc -Replacing constant pointer function [7] call myFunc2 +Replacing constant pointer function [5] callexecute myFunc +Replacing constant pointer function [7] callexecute myFunc2 Successful SSA optimization Pass2ConstantCallPointerIdentification Eliminating unused constant funcPointer#0 Eliminating unused constant funcPointer#1 @@ -110,8 +112,8 @@ FINAL CONTROL FLOW GRAPH void main() main: scope:[main] from [0] phi() - [1] call myFunc - [2] call myFunc2 + [1] callexecute myFunc + [2] callexecute myFunc2 to:main::@return main::@return: scope:[main] from main [3] return @@ -171,9 +173,9 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Code // main main: { - // [1] call myFunc + // [1] callexecute myFunc -- jsr jsr myFunc - // [2] call myFunc2 + // [2] callexecute myFunc2 -- jsr jsr myFunc2 jmp __breturn // main::@return @@ -244,9 +246,9 @@ Score: 42 // main main: { // (*funcPointer)() - // [1] call myFunc + // [1] callexecute myFunc -- jsr jsr myFunc - // [2] call myFunc2 + // [2] callexecute myFunc2 -- jsr jsr myFunc2 // main::@return // } diff --git a/src/test/ref/function-pointer-noarg-call-12.cfg b/src/test/ref/function-pointer-noarg-call-12.cfg index 0eb762f2a..5a8dbc82b 100644 --- a/src/test/ref/function-pointer-noarg-call-12.cfg +++ b/src/test/ref/function-pointer-noarg-call-12.cfg @@ -4,9 +4,9 @@ main: scope:[main] from [0] *addrtable = &myFunc [1] *(addrtable+1*SIZEOF_POINTER) = &myFunc2 [2] main::fn#0 = *addrtable - [3] call *main::fn#0 + [3] callexecute *main::fn#0 [4] main::fn#1 = *(addrtable+1*SIZEOF_POINTER) - [5] call *main::fn#1 + [5] callexecute *main::fn#1 to:main::@return main::@return: scope:[main] from main [6] return diff --git a/src/test/ref/function-pointer-noarg-call-12.log b/src/test/ref/function-pointer-noarg-call-12.log index e6051e715..518b665e2 100644 --- a/src/test/ref/function-pointer-noarg-call-12.log +++ b/src/test/ref/function-pointer-noarg-call-12.log @@ -1,3 +1,5 @@ +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::fn +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::fn CONTROL FLOW GRAPH SSA @@ -25,10 +27,10 @@ main: scope:[main] from __start addrtable[main::$3] = &myFunc2 main::$4 = 0 * SIZEOF_POINTER main::fn#0 = addrtable[main::$4] - call *main::fn#0 + callexecute *main::fn#0 main::$5 = 1 * SIZEOF_POINTER main::fn#1 = addrtable[main::$5] - call *main::fn#1 + callexecute *main::fn#1 to:main::@return main::@return: scope:[main] from main return @@ -120,6 +122,7 @@ Finalized unsigned number type (word) $100 Finalized unsigned number type (word) $100 Successful SSA optimization PassNFinalizeNumberTypeConversions CALL GRAPH +Calls in [main] to null:3 null:5 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes @@ -131,9 +134,9 @@ main: scope:[main] from [0] *addrtable = &myFunc [1] *(addrtable+1*SIZEOF_POINTER) = &myFunc2 [2] main::fn#0 = *addrtable - [3] call *main::fn#0 + [3] callexecute *main::fn#0 [4] main::fn#1 = *(addrtable+1*SIZEOF_POINTER) - [5] call *main::fn#1 + [5] callexecute *main::fn#1 to:main::@return main::@return: scope:[main] from main [6] return @@ -159,8 +162,8 @@ myFunc::@return: scope:[myFunc] from myFunc VARIABLE REGISTER WEIGHTS void main() void()* main::fn -void()* main::fn#0 2.0 -void()* main::fn#1 2.0 +void()* main::fn#0 20.0 +void()* main::fn#1 20.0 void myFunc() void myFunc2() @@ -175,15 +178,15 @@ Allocated zp[2]:4 [ main::fn#1 ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] *addrtable = &myFunc [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] *(addrtable+1*SIZEOF_POINTER) = &myFunc2 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [2] main::fn#0 = *addrtable [ main::fn#0 ] ( [ main::fn#0 ] { } ) always clobbers reg byte a -Statement [3] call *main::fn#0 [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y -Statement [4] main::fn#1 = *(addrtable+1*SIZEOF_POINTER) [ main::fn#1 ] ( [ main::fn#1 ] { } ) always clobbers reg byte a -Statement [5] call *main::fn#1 [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [2] main::fn#0 = *addrtable [ ] ( [ ] { } ) always clobbers reg byte a +Statement [3] callexecute *main::fn#0 [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [4] main::fn#1 = *(addrtable+1*SIZEOF_POINTER) [ ] ( [ ] { } ) always clobbers reg byte a +Statement [5] callexecute *main::fn#1 [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y Potential registers zp[2]:2 [ main::fn#0 ] : zp[2]:2 , Potential registers zp[2]:4 [ main::fn#1 ] : zp[2]:4 , REGISTER UPLIFT SCOPES -Uplift Scope [main] 2: zp[2]:2 [ main::fn#0 ] 2: zp[2]:4 [ main::fn#1 ] +Uplift Scope [main] 20: zp[2]:2 [ main::fn#0 ] 20: zp[2]:4 [ main::fn#1 ] Uplift Scope [myFunc] Uplift Scope [myFunc2] Uplift Scope [] @@ -227,14 +230,14 @@ main: { sta.z fn lda addrtable+1 sta.z fn+1 - // [3] call *main::fn#0 + // [3] callexecute *main::fn#0 jsr bi_fn // [4] main::fn#1 = *(addrtable+1*SIZEOF_POINTER) -- pprz1=_deref_qprc1 lda addrtable+1*SIZEOF_POINTER sta.z fn_1 lda addrtable+1*SIZEOF_POINTER+1 sta.z fn_1+1 - // [5] call *main::fn#1 + // [5] callexecute *main::fn#1 jsr bi_fn_1 jmp __breturn // main::@return @@ -287,8 +290,8 @@ constant byte SIZEOF_POINTER = 2 constant void()** addrtable[$100] = { fill( $100, 0) } void main() void()* main::fn -void()* main::fn#0 fn zp[2]:2 2.0 -void()* main::fn#1 fn_1 zp[2]:4 2.0 +void()* main::fn#0 fn zp[2]:2 20.0 +void()* main::fn#1 fn_1 zp[2]:4 20.0 void myFunc() constant byte* const myFunc::BORDER_COLOR = (byte*) 53280 void myFunc2() @@ -338,7 +341,7 @@ main: { lda addrtable+1 sta.z fn+1 // (*fn)() - // [3] call *main::fn#0 + // [3] callexecute *main::fn#0 jsr bi_fn // fn = addrtable[1] // [4] main::fn#1 = *(addrtable+1*SIZEOF_POINTER) -- pprz1=_deref_qprc1 @@ -347,7 +350,7 @@ main: { lda addrtable+1*SIZEOF_POINTER+1 sta.z fn_1+1 // (*fn)() - // [5] call *main::fn#1 + // [5] callexecute *main::fn#1 jsr bi_fn_1 // main::@return // } diff --git a/src/test/ref/function-pointer-noarg-call-12.sym b/src/test/ref/function-pointer-noarg-call-12.sym index 5a8f8861f..88b6aa843 100644 --- a/src/test/ref/function-pointer-noarg-call-12.sym +++ b/src/test/ref/function-pointer-noarg-call-12.sym @@ -2,8 +2,8 @@ constant byte SIZEOF_POINTER = 2 constant void()** addrtable[$100] = { fill( $100, 0) } void main() void()* main::fn -void()* main::fn#0 fn zp[2]:2 2.0 -void()* main::fn#1 fn_1 zp[2]:4 2.0 +void()* main::fn#0 fn zp[2]:2 20.0 +void()* main::fn#1 fn_1 zp[2]:4 20.0 void myFunc() constant byte* const myFunc::BORDER_COLOR = (byte*) 53280 void myFunc2() diff --git a/src/test/ref/function-pointer-noarg-call-14.cfg b/src/test/ref/function-pointer-noarg-call-14.cfg index 029456b8a..c778a997a 100644 --- a/src/test/ref/function-pointer-noarg-call-14.cfg +++ b/src/test/ref/function-pointer-noarg-call-14.cfg @@ -113,7 +113,7 @@ gotoxy::@return: scope:[gotoxy] from gotoxy::@2 void f1(void()* f1::fn) f1: scope:[f1] from main main::@1 [49] f1::fn#2 = phi( main/&hello, main::@1/&world ) - [50] call *f1::fn#2 + [50] callexecute *f1::fn#2 to:f1::@return f1::@return: scope:[f1] from f1 [51] return diff --git a/src/test/ref/function-pointer-noarg-call-14.log b/src/test/ref/function-pointer-noarg-call-14.log index 1161c0f5b..3422e5da2 100644 --- a/src/test/ref/function-pointer-noarg-call-14.log +++ b/src/test/ref/function-pointer-noarg-call-14.log @@ -11,6 +11,7 @@ Eliminating unused variable with no statement gotoxy::$4 Eliminating unused variable with no statement printf_buffer Eliminating unused variable with no statement hello::$0 Eliminating unused variable with no statement world::$0 +Calling convention STACK_CALL adding prepare/execute/finalize for call *f1::fn CONTROL FLOW GRAPH SSA @@ -282,7 +283,7 @@ conio_c64_init::@return: scope:[conio_c64_init] from conio_c64_init::@3 void f1(void()* f1::fn) f1: scope:[f1] from main main::@1 f1::fn#2 = phi( main/f1::fn#0, main::@1/f1::fn#1 ) - call *f1::fn#2 + callexecute *f1::fn#2 to:f1::@return f1::@return: scope:[f1] from f1 return @@ -866,6 +867,7 @@ Calls in [hello] to cputs:16 Calls in [conio_c64_init] to gotoxy:24 Calls in [main] to f1:29 f1:31 Calls in [cputs] to cputc:42 +Calls in [f1] to null:60 Calls in [cputc] to cputln:68 cputln:72 Calls in [cputln] to cscroll:78 Calls in [cscroll] to memcpy:84 memcpy:86 memset:88 memset:90 @@ -1035,7 +1037,7 @@ gotoxy::@return: scope:[gotoxy] from gotoxy::@2 void f1(void()* f1::fn) f1: scope:[f1] from main main::@1 [49] f1::fn#2 = phi( main/&hello, main::@1/&world ) - [50] call *f1::fn#2 + [50] callexecute *f1::fn#2 to:f1::@return f1::@return: scope:[f1] from f1 [51] return @@ -1313,7 +1315,7 @@ Statement [44] gotoxy::$5 = DEFAULT_SCREEN + gotoxy::line_offset#0 [ gotoxy::lin Statement [45] conio_line_text = gotoxy::$5 [ gotoxy::line_offset#0 ] ( gotoxy:20 [ gotoxy::line_offset#0 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:20 [ gotoxy::line_offset#0 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } ) always clobbers reg byte a Statement [46] gotoxy::$6 = COLORRAM + gotoxy::line_offset#0 [ gotoxy::$6 ] ( gotoxy:20 [ gotoxy::$6 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:20 [ gotoxy::$6 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } ) always clobbers reg byte a Statement [47] conio_line_color = gotoxy::$6 [ ] ( gotoxy:20 [ ] { { gotoxy::y#2 = conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:20 [ ] { { gotoxy::y#2 = conio_c64_init::line#2 } } ) always clobbers reg byte a -Statement [50] call *f1::fn#2 [ ] ( main:7::f1:23 [ ] { } main:7::f1:25 [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [50] callexecute *f1::fn#2 [ ] ( main:7::f1:23 [ ] { } main:7::f1:25 [ ] { } ) always clobbers reg byte a reg byte x reg byte y Statement [53] conio_line_text[conio_cursor_x] = cputc::c#0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:10::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:13::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte y Statement [54] conio_line_color[conio_cursor_x] = LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:10::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:13::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y Statement [56] if(conio_cursor_x!=$28) goto cputc::@return [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:10::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:13::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a @@ -1348,7 +1350,7 @@ Statement [44] gotoxy::$5 = DEFAULT_SCREEN + gotoxy::line_offset#0 [ gotoxy::lin Statement [45] conio_line_text = gotoxy::$5 [ gotoxy::line_offset#0 ] ( gotoxy:20 [ gotoxy::line_offset#0 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:20 [ gotoxy::line_offset#0 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } ) always clobbers reg byte a Statement [46] gotoxy::$6 = COLORRAM + gotoxy::line_offset#0 [ gotoxy::$6 ] ( gotoxy:20 [ gotoxy::$6 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:20 [ gotoxy::$6 ] { { gotoxy::y#2 = conio_c64_init::line#2 } } ) always clobbers reg byte a Statement [47] conio_line_color = gotoxy::$6 [ ] ( gotoxy:20 [ ] { { gotoxy::y#2 = conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:20 [ ] { { gotoxy::y#2 = conio_c64_init::line#2 } } ) always clobbers reg byte a -Statement [50] call *f1::fn#2 [ ] ( main:7::f1:23 [ ] { } main:7::f1:25 [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [50] callexecute *f1::fn#2 [ ] ( main:7::f1:23 [ ] { } main:7::f1:25 [ ] { } ) always clobbers reg byte a reg byte x reg byte y Statement [53] conio_line_text[conio_cursor_x] = cputc::c#0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:10::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:13::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte y Statement [54] conio_line_color[conio_cursor_x] = LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:10::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:13::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y Statement [56] if(conio_cursor_x!=$28) goto cputc::@return [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:10::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:13::cputc:34 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a @@ -1774,7 +1776,7 @@ gotoxy: { // f1(void()* zp(4) fn) f1: { .label fn = 4 - // [50] call *f1::fn#2 + // [50] callexecute *f1::fn#2 jsr bi_fn jmp __breturn // f1::@return @@ -2582,7 +2584,7 @@ gotoxy: { f1: { .label fn = 4 // (*fn)() - // [50] call *f1::fn#2 + // [50] callexecute *f1::fn#2 jsr bi_fn // f1::@return // } diff --git a/src/test/ref/function-pointer-noarg-call-2.cfg b/src/test/ref/function-pointer-noarg-call-2.cfg index cc3538a42..78226c2a2 100644 --- a/src/test/ref/function-pointer-noarg-call-2.cfg +++ b/src/test/ref/function-pointer-noarg-call-2.cfg @@ -32,5 +32,5 @@ main::@3: scope:[main] from main::@2 to:main::@4 main::@4: scope:[main] from main::@2 main::@3 [10] main::f#3 = phi( main::@3/&fn1, main::@2/&fn2 ) - [11] call *main::f#3 + [11] callexecute *main::f#3 to:main::@1 diff --git a/src/test/ref/function-pointer-noarg-call-2.log b/src/test/ref/function-pointer-noarg-call-2.log index 6737f545a..e7ded3ecf 100644 --- a/src/test/ref/function-pointer-noarg-call-2.log +++ b/src/test/ref/function-pointer-noarg-call-2.log @@ -1,5 +1,6 @@ Resolved forward reference fn1 to void fn1() Resolved forward reference fn2 to void fn2() +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f CONTROL FLOW GRAPH SSA @@ -30,7 +31,7 @@ main::@5: scope:[main] from main::@2 main::@4: scope:[main] from main::@3 main::@5 main::i#4 = phi( main::@3/main::i#5, main::@5/main::i#6 ) main::f#3 = phi( main::@3/main::f#1, main::@5/main::f#2 ) - call *main::f#3 + callexecute *main::f#3 to:main::@1 main::@return: scope:[main] from main::@1 return @@ -132,6 +133,7 @@ Adding NOP phi() at start of main Adding NOP phi() at start of main::@5 Adding NOP phi() at start of main::@3 CALL GRAPH +Calls in [main] to null:11 Created 2 initial phi equivalence classes Coalesced [12] main::i#7 = main::i#1 @@ -175,7 +177,7 @@ main::@3: scope:[main] from main::@2 to:main::@4 main::@4: scope:[main] from main::@2 main::@3 [10] main::f#3 = phi( main::@3/&fn1, main::@2/&fn2 ) - [11] call *main::f#3 + [11] callexecute *main::f#3 to:main::@1 @@ -187,7 +189,7 @@ byte~ main::$0 22.0 void()* main::f void()* main::f#3 byte main::i -byte main::i#1 5.5 +byte main::i#1 16.5 byte main::i#2 22.0 Initial phi equivalence classes @@ -202,18 +204,18 @@ Allocated zp[1]:2 [ main::i#2 main::i#1 ] Allocated zp[2]:3 [ main::f#3 ] Allocated zp[1]:5 [ main::$0 ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [11] call *main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [11] callexecute *main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [7] main::$0 = main::i#1 & 1 [ main::i#1 main::$0 ] ( [ main::i#1 main::$0 ] { } ) always clobbers reg byte a -Statement [11] call *main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [7] main::$0 = main::i#1 & 1 [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a +Statement [11] callexecute *main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , Potential registers zp[2]:3 [ main::f#3 ] : zp[2]:3 , Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 27.5: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:5 [ main::$0 ] 0: zp[2]:3 [ main::f#3 ] +Uplift Scope [main] 38.5: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:5 [ main::$0 ] 0: zp[2]:3 [ main::f#3 ] Uplift Scope [fn1] Uplift Scope [fn2] Uplift Scope [] @@ -307,7 +309,7 @@ main: { jmp __b4 // main::@4 __b4: - // [11] call *main::f#3 + // [11] callexecute *main::f#3 jsr bi_f // [5] phi from main::@4 to main::@1 [phi:main::@4->main::@1] __b1_from___b4: @@ -349,7 +351,7 @@ byte~ main::$0 reg byte a 22.0 void()* main::f void()* main::f#3 f zp[2]:3 byte main::i -byte main::i#1 i zp[1]:2 5.5 +byte main::i#1 i zp[1]:2 16.5 byte main::i#2 i zp[1]:2 22.0 zp[1]:2 [ main::i#2 main::i#1 ] @@ -436,7 +438,7 @@ main: { // main::@4 __b4: // (*f)() - // [11] call *main::f#3 + // [11] callexecute *main::f#3 jsr bi_f // [5] phi from main::@4 to main::@1 [phi:main::@4->main::@1] // [5] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy diff --git a/src/test/ref/function-pointer-noarg-call-2.sym b/src/test/ref/function-pointer-noarg-call-2.sym index 1054fef5b..35e57cd1b 100644 --- a/src/test/ref/function-pointer-noarg-call-2.sym +++ b/src/test/ref/function-pointer-noarg-call-2.sym @@ -7,7 +7,7 @@ byte~ main::$0 reg byte a 22.0 void()* main::f void()* main::f#3 f zp[2]:3 byte main::i -byte main::i#1 i zp[1]:2 5.5 +byte main::i#1 i zp[1]:2 16.5 byte main::i#2 i zp[1]:2 22.0 zp[1]:2 [ main::i#2 main::i#1 ] diff --git a/src/test/ref/function-pointer-noarg-call-3.cfg b/src/test/ref/function-pointer-noarg-call-3.cfg index 766b80770..2656452bb 100644 --- a/src/test/ref/function-pointer-noarg-call-3.cfg +++ b/src/test/ref/function-pointer-noarg-call-3.cfg @@ -30,7 +30,7 @@ main::@2: scope:[main] from main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [10] main::$0 = getfn::return#0 - [11] call *main::$0 + [11] callexecute *main::$0 to:main::@1 void()* getfn(byte getfn::b) diff --git a/src/test/ref/function-pointer-noarg-call-3.log b/src/test/ref/function-pointer-noarg-call-3.log index fe4b070c4..256cb3cc0 100644 --- a/src/test/ref/function-pointer-noarg-call-3.log +++ b/src/test/ref/function-pointer-noarg-call-3.log @@ -1,5 +1,6 @@ Resolved forward reference fn1 to void fn1() Resolved forward reference fn2 to void fn2() +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::$0 CONTROL FLOW GRAPH SSA @@ -22,7 +23,7 @@ main::@3: scope:[main] from main::@2 main::i#4 = phi( main::@2/main::i#1 ) getfn::return#4 = phi( main::@2/getfn::return#0 ) main::$0 = getfn::return#4 - call *main::$0 + callexecute *main::$0 to:main::@1 main::@return: scope:[main] from main::@1 return @@ -147,7 +148,7 @@ Adding NOP phi() at start of main Adding NOP phi() at start of getfn::@2 Adding NOP phi() at start of getfn::@1 CALL GRAPH -Calls in [main] to getfn:8 +Calls in [main] to getfn:8 null:11 Created 2 initial phi equivalence classes Coalesced [12] main::i#5 = main::i#1 @@ -189,7 +190,7 @@ main::@2: scope:[main] from main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [10] main::$0 = getfn::return#0 - [11] call *main::$0 + [11] callexecute *main::$0 to:main::@1 void()* getfn(byte getfn::b) @@ -217,9 +218,9 @@ void()* getfn::return void()* getfn::return#0 22.0 void()* getfn::return#3 3.6666666666666665 void main() -void()*~ main::$0 11.0 +void()*~ main::$0 110.0 byte main::i -byte main::i#1 5.5 +byte main::i#1 16.5 byte main::i#2 22.0 Initial phi equivalence classes @@ -243,15 +244,15 @@ Allocated zp[2]:6 [ getfn::return#0 ] Allocated zp[2]:8 [ main::$0 ] Allocated zp[1]:10 [ getfn::$0 ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [9] getfn::return#0 = getfn::return#3 [ main::i#1 getfn::return#0 ] ( [ main::i#1 getfn::return#0 ] { { getfn::b#0 = main::i#1 } { getfn::return#0 = getfn::return#3 } } ) always clobbers reg byte a +Statement [9] getfn::return#0 = getfn::return#3 [ getfn::return#0 ] ( [ getfn::return#0 ] { { getfn::b#0 = main::i#1 } { getfn::return#0 = getfn::return#3 } } ) always clobbers reg byte a +Statement [10] main::$0 = getfn::return#0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [11] callexecute *main::$0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [10] main::$0 = getfn::return#0 [ main::i#1 main::$0 ] ( [ main::i#1 main::$0 ] { } ) always clobbers reg byte a -Statement [11] call *main::$0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [9] getfn::return#0 = getfn::return#3 [ main::i#1 getfn::return#0 ] ( [ main::i#1 getfn::return#0 ] { { getfn::b#0 = main::i#1 } { getfn::return#0 = getfn::return#3 } } ) always clobbers reg byte a -Statement [10] main::$0 = getfn::return#0 [ main::i#1 main::$0 ] ( [ main::i#1 main::$0 ] { } ) always clobbers reg byte a -Statement [11] call *main::$0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [9] getfn::return#0 = getfn::return#3 [ getfn::return#0 ] ( [ getfn::return#0 ] { { getfn::b#0 = main::i#1 } { getfn::return#0 = getfn::return#3 } } ) always clobbers reg byte a +Statement [10] main::$0 = getfn::return#0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [11] callexecute *main::$0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , Potential registers zp[2]:3 [ getfn::return#3 ] : zp[2]:3 , Potential registers zp[1]:5 [ getfn::b#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , @@ -261,13 +262,13 @@ Potential registers zp[1]:10 [ getfn::$0 ] : zp[1]:10 , reg byte a , reg byte x REGISTER UPLIFT SCOPES Uplift Scope [getfn] 202: zp[1]:10 [ getfn::$0 ] 112: zp[1]:5 [ getfn::b#0 ] 22: zp[2]:6 [ getfn::return#0 ] 3.67: zp[2]:3 [ getfn::return#3 ] -Uplift Scope [main] 27.5: zp[1]:2 [ main::i#2 main::i#1 ] 11: zp[2]:8 [ main::$0 ] +Uplift Scope [main] 110: zp[2]:8 [ main::$0 ] 38.5: zp[1]:2 [ main::i#2 main::i#1 ] Uplift Scope [fn1] Uplift Scope [fn2] Uplift Scope [] Uplifting [getfn] best 731 combination reg byte a [ getfn::$0 ] reg byte a [ getfn::b#0 ] zp[2]:6 [ getfn::return#0 ] zp[2]:3 [ getfn::return#3 ] -Uplifting [main] best 731 combination zp[1]:2 [ main::i#2 main::i#1 ] zp[2]:8 [ main::$0 ] +Uplifting [main] best 731 combination zp[2]:8 [ main::$0 ] zp[1]:2 [ main::i#2 main::i#1 ] Uplifting [fn1] best 731 combination Uplifting [fn2] best 731 combination Uplifting [] best 731 combination @@ -338,7 +339,7 @@ main: { // main::@3 __b3: // [10] main::$0 = getfn::return#0 - // [11] call *main::$0 + // [11] callexecute *main::$0 jsr bi___0 // [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1] __b1_from___b3: @@ -425,9 +426,9 @@ void()* getfn::return void()* getfn::return#0 return zp[2]:3 22.0 void()* getfn::return#3 return zp[2]:3 3.6666666666666665 void main() -void()*~ main::$0 zp[2]:3 11.0 +void()*~ main::$0 zp[2]:3 110.0 byte main::i -byte main::i#1 i zp[1]:2 5.5 +byte main::i#1 i zp[1]:2 16.5 byte main::i#2 i zp[1]:2 22.0 zp[1]:2 [ main::i#2 main::i#1 ] @@ -497,7 +498,7 @@ main: { // main::@3 // [10] main::$0 = getfn::return#0 // (*getfn(++i))() - // [11] call *main::$0 + // [11] callexecute *main::$0 jsr bi___0 // [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1] // [5] phi main::i#2 = main::i#1 [phi:main::@3->main::@1#0] -- register_copy diff --git a/src/test/ref/function-pointer-noarg-call-3.sym b/src/test/ref/function-pointer-noarg-call-3.sym index 55f95e0ef..515ce2e0e 100644 --- a/src/test/ref/function-pointer-noarg-call-3.sym +++ b/src/test/ref/function-pointer-noarg-call-3.sym @@ -10,9 +10,9 @@ void()* getfn::return void()* getfn::return#0 return zp[2]:3 22.0 void()* getfn::return#3 return zp[2]:3 3.6666666666666665 void main() -void()*~ main::$0 zp[2]:3 11.0 +void()*~ main::$0 zp[2]:3 110.0 byte main::i -byte main::i#1 i zp[1]:2 5.5 +byte main::i#1 i zp[1]:2 16.5 byte main::i#2 i zp[1]:2 22.0 zp[1]:2 [ main::i#2 main::i#1 ] diff --git a/src/test/ref/function-pointer-noarg-call-4.cfg b/src/test/ref/function-pointer-noarg-call-4.cfg index 8d14dc99f..1d7f8e6fd 100644 --- a/src/test/ref/function-pointer-noarg-call-4.cfg +++ b/src/test/ref/function-pointer-noarg-call-4.cfg @@ -19,5 +19,5 @@ main::@2: scope:[main] from main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [5] phi() - [6] call fn1 + [6] callexecute fn1 to:main::@1 diff --git a/src/test/ref/function-pointer-noarg-call-4.log b/src/test/ref/function-pointer-noarg-call-4.log index 94e5eeff5..7903722c5 100644 --- a/src/test/ref/function-pointer-noarg-call-4.log +++ b/src/test/ref/function-pointer-noarg-call-4.log @@ -1,4 +1,5 @@ Resolved forward reference fn1 to void fn1() +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::$0 CONTROL FLOW GRAPH SSA @@ -21,7 +22,7 @@ main::@3: scope:[main] from main::@2 main::i#4 = phi( main::@2/main::i#1 ) getfn::return#3 = phi( main::@2/getfn::return#0 ) main::$0 = getfn::return#3 - call *main::$0 + callexecute *main::$0 to:main::@1 main::@return: scope:[main] from main::@1 return @@ -91,7 +92,7 @@ Constant getfn::return#0 = getfn::return#1 Successful SSA optimization Pass2ConstantIdentification Constant main::$0 = getfn::return#0 Successful SSA optimization Pass2ConstantIdentification -Replacing constant pointer function [8] call fn1 +Replacing constant pointer function [8] callexecute fn1 Successful SSA optimization Pass2ConstantCallPointerIdentification if() condition always true - replacing block destination [2] if(true) goto main::@2 Successful SSA optimization Pass2ConstantIfs @@ -150,7 +151,7 @@ main::@2: scope:[main] from main::@1 to:main::@3 main::@3: scope:[main] from main::@2 [5] phi() - [6] call fn1 + [6] callexecute fn1 to:main::@1 null depth in calling loop Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@2 main::@1 in scope fn1 @@ -223,7 +224,7 @@ main: { jmp __b3 // main::@3 __b3: - // [6] call fn1 + // [6] callexecute fn1 -- jsr jsr fn1 // [3] phi from main::@3 to main::@1 [phi:main::@3->main::@1] __b1_from___b3: @@ -300,7 +301,7 @@ main: { // [5] phi from main::@2 to main::@3 [phi:main::@2->main::@3] // main::@3 // (*getfn(++i))() - // [6] call fn1 + // [6] callexecute fn1 -- jsr jsr fn1 // [3] phi from main::@3 to main::@1 [phi:main::@3->main::@1] // [3] phi main::i#2 = main::i#1 [phi:main::@3->main::@1#0] -- register_copy diff --git a/src/test/ref/function-pointer-noarg-call-5.cfg b/src/test/ref/function-pointer-noarg-call-5.cfg index c0997f8a2..ca9824ec8 100644 --- a/src/test/ref/function-pointer-noarg-call-5.cfg +++ b/src/test/ref/function-pointer-noarg-call-5.cfg @@ -11,7 +11,7 @@ main::@2: scope:[main] from main::@1 [3] main::$0 = main::i#1 & 1 [4] main::$2 = main::$0 << 1 [5] main::f#0 = fns[main::$2] - [6] call *main::f#0 + [6] callexecute *main::f#0 to:main::@1 void fn2() diff --git a/src/test/ref/function-pointer-noarg-call-5.log b/src/test/ref/function-pointer-noarg-call-5.log index 2581274c6..2cca16f0a 100644 --- a/src/test/ref/function-pointer-noarg-call-5.log +++ b/src/test/ref/function-pointer-noarg-call-5.log @@ -1,3 +1,4 @@ +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f CONTROL FLOW GRAPH SSA @@ -31,7 +32,7 @@ main::@2: scope:[main] from main::@1 main::$0 = main::i#1 & 1 main::$2 = main::$0 * SIZEOF_POINTER main::f#0 = fns[main::$2] - call *main::f#0 + callexecute *main::f#0 to:main::@1 main::@return: scope:[main] from main::@1 return @@ -102,6 +103,7 @@ Finalized unsigned number type (byte) 2 Successful SSA optimization PassNFinalizeNumberTypeConversions Adding NOP phi() at start of main CALL GRAPH +Calls in [main] to null:6 Created 1 initial phi equivalence classes Coalesced [7] main::i#4 = main::i#1 @@ -122,7 +124,7 @@ main::@2: scope:[main] from main::@1 [3] main::$0 = main::i#1 & 1 [4] main::$2 = main::$0 << 1 [5] main::f#0 = fns[main::$2] - [6] call *main::f#0 + [6] callexecute *main::f#0 to:main::@1 void fn2() @@ -149,9 +151,9 @@ void main() byte~ main::$0 22.0 byte~ main::$2 22.0 void()* main::f -void()* main::f#0 11.0 +void()* main::f#0 110.0 byte main::i -byte main::i#1 6.6000000000000005 +byte main::i#1 16.5 byte main::i#2 22.0 Initial phi equivalence classes @@ -169,28 +171,28 @@ Allocated zp[1]:3 [ main::$0 ] Allocated zp[1]:4 [ main::$2 ] Allocated zp[2]:5 [ main::f#0 ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [4] main::$2 = main::$0 << 1 [ main::i#1 main::$2 ] ( [ main::i#1 main::$2 ] { } ) always clobbers reg byte a +Statement [4] main::$2 = main::$0 << 1 [ main::$2 ] ( [ main::$2 ] { } ) always clobbers reg byte a +Statement [5] main::f#0 = fns[main::$2] [ ] ( [ ] { } ) always clobbers reg byte a +Statement [6] callexecute *main::f#0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [5] main::f#0 = fns[main::$2] [ main::i#1 main::f#0 ] ( [ main::i#1 main::f#0 ] { } ) always clobbers reg byte a -Statement [6] call *main::f#0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [3] main::$0 = main::i#1 & 1 [ main::i#1 main::$0 ] ( [ main::i#1 main::$0 ] { } ) always clobbers reg byte a -Statement [4] main::$2 = main::$0 << 1 [ main::i#1 main::$2 ] ( [ main::i#1 main::$2 ] { } ) always clobbers reg byte a -Statement [5] main::f#0 = fns[main::$2] [ main::i#1 main::f#0 ] ( [ main::i#1 main::f#0 ] { } ) always clobbers reg byte a -Statement [6] call *main::f#0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [3] main::$0 = main::i#1 & 1 [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a +Statement [4] main::$2 = main::$0 << 1 [ main::$2 ] ( [ main::$2 ] { } ) always clobbers reg byte a +Statement [5] main::f#0 = fns[main::$2] [ ] ( [ ] { } ) always clobbers reg byte a +Statement [6] callexecute *main::f#0 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , Potential registers zp[1]:3 [ main::$0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:4 [ main::$2 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , Potential registers zp[2]:5 [ main::f#0 ] : zp[2]:5 , REGISTER UPLIFT SCOPES -Uplift Scope [main] 28.6: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:3 [ main::$0 ] 22: zp[1]:4 [ main::$2 ] 11: zp[2]:5 [ main::f#0 ] +Uplift Scope [main] 110: zp[2]:5 [ main::f#0 ] 38.5: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:3 [ main::$0 ] 22: zp[1]:4 [ main::$2 ] Uplift Scope [fn1] Uplift Scope [fn2] Uplift Scope [] -Uplifting [main] best 570 combination zp[1]:2 [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] reg byte a [ main::$2 ] zp[2]:5 [ main::f#0 ] +Uplifting [main] best 570 combination zp[2]:5 [ main::f#0 ] zp[1]:2 [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] reg byte a [ main::$2 ] Uplifting [fn1] best 570 combination Uplifting [fn2] best 570 combination Uplifting [] best 570 combination @@ -240,7 +242,7 @@ main: { sta.z f lda fns+1,y sta.z f+1 - // [6] call *main::f#0 + // [6] callexecute *main::f#0 jsr bi_f // [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1] __b1_from___b2: @@ -301,9 +303,9 @@ void main() byte~ main::$0 reg byte a 22.0 byte~ main::$2 reg byte a 22.0 void()* main::f -void()* main::f#0 f zp[2]:3 11.0 +void()* main::f#0 f zp[2]:3 110.0 byte main::i -byte main::i#1 i zp[1]:2 6.6000000000000005 +byte main::i#1 i zp[1]:2 16.5 byte main::i#2 i zp[1]:2 22.0 zp[1]:2 [ main::i#2 main::i#1 ] @@ -356,7 +358,7 @@ main: { lda fns+1,y sta.z f+1 // (*f)() - // [6] call *main::f#0 + // [6] callexecute *main::f#0 jsr bi_f // [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1] // [1] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy diff --git a/src/test/ref/function-pointer-noarg-call-5.sym b/src/test/ref/function-pointer-noarg-call-5.sym index 91881b3d2..fdeec464a 100644 --- a/src/test/ref/function-pointer-noarg-call-5.sym +++ b/src/test/ref/function-pointer-noarg-call-5.sym @@ -7,9 +7,9 @@ void main() byte~ main::$0 reg byte a 22.0 byte~ main::$2 reg byte a 22.0 void()* main::f -void()* main::f#0 f zp[2]:3 11.0 +void()* main::f#0 f zp[2]:3 110.0 byte main::i -byte main::i#1 i zp[1]:2 6.6000000000000005 +byte main::i#1 i zp[1]:2 16.5 byte main::i#2 i zp[1]:2 22.0 zp[1]:2 [ main::i#2 main::i#1 ] diff --git a/src/test/ref/function-pointer-noarg-call-6.cfg b/src/test/ref/function-pointer-noarg-call-6.cfg index 5d42845d1..2459cf94a 100644 --- a/src/test/ref/function-pointer-noarg-call-6.cfg +++ b/src/test/ref/function-pointer-noarg-call-6.cfg @@ -12,7 +12,7 @@ main::@return: scope:[main] from main::@1 to:@return main::@2: scope:[main] from main::@1 [4] phi() - [5] call fn1 + [5] callexecute fn1 [6] *main::cols#2 = ++ *main::cols#2 [7] main::cols#1 = ++ main::cols#2 to:main::@1 diff --git a/src/test/ref/function-pointer-noarg-call-6.log b/src/test/ref/function-pointer-noarg-call-6.log index 00dfd44af..5c2376b11 100644 --- a/src/test/ref/function-pointer-noarg-call-6.log +++ b/src/test/ref/function-pointer-noarg-call-6.log @@ -1,3 +1,4 @@ +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::cls CONTROL FLOW GRAPH SSA @@ -30,7 +31,7 @@ main::@1: scope:[main] from main main::@2 to:main::@return main::@2: scope:[main] from main::@1 main::cols#3 = phi( main::@1/main::cols#2 ) - call *main::cls + callexecute *main::cls *main::cols#3 = ++ *main::cols#3 main::cols#1 = ++ main::cols#3 to:main::@1 @@ -81,7 +82,7 @@ Successful SSA optimization Pass2ConditionalJumpSimplification Constant fn1::screen#0 = (byte*) 1024 Constant main::cols#0 = (byte*) 55296 Successful SSA optimization Pass2ConstantIdentification -Replacing constant pointer function [11] call fn1 +Replacing constant pointer function [11] callexecute fn1 Successful SSA optimization Pass2ConstantCallPointerIdentification Eliminating unused constant main::cls Successful SSA optimization PassNEliminateUnusedVars @@ -132,7 +133,7 @@ main::@return: scope:[main] from main::@1 to:@return main::@2: scope:[main] from main::@1 [4] phi() - [5] call fn1 + [5] callexecute fn1 [6] *main::cols#2 = ++ *main::cols#2 [7] main::cols#1 = ++ main::cols#2 to:main::@1 @@ -235,7 +236,7 @@ main: { jmp __b2 // main::@2 __b2: - // [5] call fn1 + // [5] callexecute fn1 -- jsr jsr fn1 // [6] *main::cols#2 = ++ *main::cols#2 -- _deref_pbuz1=_inc__deref_pbuz1 ldy #0 @@ -383,7 +384,7 @@ main: { // main::@2 __b2: // (*cls)() - // [5] call fn1 + // [5] callexecute fn1 -- jsr jsr fn1 // (*cols)++; // [6] *main::cols#2 = ++ *main::cols#2 -- _deref_pbuz1=_inc__deref_pbuz1 diff --git a/src/test/ref/function-pointer-noarg-call-7.cfg b/src/test/ref/function-pointer-noarg-call-7.cfg index 08b59afc9..2faefdbb7 100644 --- a/src/test/ref/function-pointer-noarg-call-7.cfg +++ b/src/test/ref/function-pointer-noarg-call-7.cfg @@ -44,7 +44,7 @@ do10: scope:[do10] from main to:do10::@1 do10::@1: scope:[do10] from do10 do10::@1 [16] do10::i#2 = phi( do10/0, do10::@1/do10::i#1 ) - [17] call hello + [17] callexecute hello [18] do10::i#1 = ++ do10::i#2 [19] if(do10::i#1!=$a) goto do10::@1 to:do10::@return diff --git a/src/test/ref/function-pointer-noarg-call-7.log b/src/test/ref/function-pointer-noarg-call-7.log index 613315276..d24ed0da9 100644 --- a/src/test/ref/function-pointer-noarg-call-7.log +++ b/src/test/ref/function-pointer-noarg-call-7.log @@ -1,4 +1,5 @@ Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *do10::fn CONTROL FLOW GRAPH SSA @@ -10,7 +11,7 @@ do10: scope:[do10] from main do10::@1: scope:[do10] from do10 do10::@1 do10::i#2 = phi( do10/do10::i#0, do10::@1/do10::i#1 ) do10::fn#1 = phi( do10/do10::fn#2, do10::@1/do10::fn#1 ) - call *do10::fn#1 + callexecute *do10::fn#1 do10::i#1 = do10::i#2 + rangenext(0,9) do10::$1 = do10::i#1 != rangelast(0,9) if(do10::$1) goto do10::@1 @@ -102,7 +103,7 @@ Constant do10::i#0 = 0 Constant hello::i#0 = 0 Constant do10::fn#0 = main::f Successful SSA optimization Pass2ConstantIdentification -Replacing constant pointer function [3] call hello +Replacing constant pointer function [3] callexecute hello Successful SSA optimization Pass2ConstantCallPointerIdentification Resolved ranged next value [4] do10::i#1 = ++ do10::i#2 to ++ Resolved ranged comparison value [6] if(do10::i#1!=rangelast(0,9)) goto do10::@1 to $a @@ -196,7 +197,7 @@ do10: scope:[do10] from main to:do10::@1 do10::@1: scope:[do10] from do10 do10::@1 [16] do10::i#2 = phi( do10/0, do10::@1/do10::i#1 ) - [17] call hello + [17] callexecute hello [18] do10::i#1 = ++ do10::i#2 [19] if(do10::i#1!=$a) goto do10::@1 to:do10::@return @@ -362,7 +363,7 @@ do10: { jmp __b1 // do10::@1 __b1: - // [17] call hello + // [17] callexecute hello -- jsr jsr hello // [18] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 inc.z i @@ -519,7 +520,7 @@ do10: { // do10::@1 __b1: // (*fn)() - // [17] call hello + // [17] callexecute hello -- jsr jsr hello // for( byte i: 0..9) // [18] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 diff --git a/src/test/ref/function-pointer-noarg-call-8.cfg b/src/test/ref/function-pointer-noarg-call-8.cfg index 178f76ef5..fe4a5841d 100644 --- a/src/test/ref/function-pointer-noarg-call-8.cfg +++ b/src/test/ref/function-pointer-noarg-call-8.cfg @@ -49,7 +49,7 @@ do10: scope:[do10] from main main::@1 to:do10::@1 do10::@1: scope:[do10] from do10 do10::@1 [19] do10::i#2 = phi( do10/0, do10::@1/do10::i#1 ) - [20] call hello + [20] callexecute hello [21] do10::i#1 = ++ do10::i#2 [22] if(do10::i#1!=$a) goto do10::@1 to:do10::@return diff --git a/src/test/ref/function-pointer-noarg-call-8.log b/src/test/ref/function-pointer-noarg-call-8.log index db22c2dc0..d8dde61b5 100644 --- a/src/test/ref/function-pointer-noarg-call-8.log +++ b/src/test/ref/function-pointer-noarg-call-8.log @@ -1,4 +1,5 @@ Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *do10::fn CONTROL FLOW GRAPH SSA @@ -10,7 +11,7 @@ do10: scope:[do10] from main main::@1 do10::@1: scope:[do10] from do10 do10::@1 do10::i#2 = phi( do10/do10::i#0, do10::@1/do10::i#1 ) do10::fn#2 = phi( do10/do10::fn#3, do10::@1/do10::fn#2 ) - call *do10::fn#2 + callexecute *do10::fn#2 do10::i#1 = do10::i#2 + rangenext(0,9) do10::$1 = do10::i#1 != rangelast(0,9) if(do10::$1) goto do10::@1 @@ -131,7 +132,7 @@ Constant inlined do10::fn#0 = main::f Successful SSA optimization Pass2ConstantInlining Identical Phi Values do10::fn#3 main::f Successful SSA optimization Pass2IdenticalPhiElimination -Replacing constant pointer function [2] call hello +Replacing constant pointer function [2] callexecute hello Successful SSA optimization Pass2ConstantCallPointerIdentification Eliminating unused constant main::f Successful SSA optimization PassNEliminateUnusedVars @@ -213,7 +214,7 @@ do10: scope:[do10] from main main::@1 to:do10::@1 do10::@1: scope:[do10] from do10 do10::@1 [19] do10::i#2 = phi( do10/0, do10::@1/do10::i#1 ) - [20] call hello + [20] callexecute hello [21] do10::i#1 = ++ do10::i#2 [22] if(do10::i#1!=$a) goto do10::@1 to:do10::@return @@ -412,7 +413,7 @@ do10: { jmp __b1 // do10::@1 __b1: - // [20] call hello + // [20] callexecute hello -- jsr jsr hello // [21] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 inc.z i @@ -600,7 +601,7 @@ do10: { // do10::@1 __b1: // (*fn)() - // [20] call hello + // [20] callexecute hello -- jsr jsr hello // for( byte i: 0..9) // [21] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 diff --git a/src/test/ref/function-pointer-noarg-call-9.cfg b/src/test/ref/function-pointer-noarg-call-9.cfg index 57c2564ab..7bd9f9b27 100644 --- a/src/test/ref/function-pointer-noarg-call-9.cfg +++ b/src/test/ref/function-pointer-noarg-call-9.cfg @@ -25,9 +25,9 @@ fn1::@return: scope:[fn1] from fn1 void main() main: scope:[main] from __start::@1 [7] phi() - [8] call fn1 + [8] callexecute fn1 [9] SCREEN[idx] = 'a' - [10] call fn1 + [10] callexecute fn1 [11] SCREEN[idx] = 'a' to:main::@return main::@return: scope:[main] from main diff --git a/src/test/ref/function-pointer-noarg-call-9.log b/src/test/ref/function-pointer-noarg-call-9.log index 6787b1a14..a5831f12c 100644 --- a/src/test/ref/function-pointer-noarg-call-9.log +++ b/src/test/ref/function-pointer-noarg-call-9.log @@ -1,4 +1,6 @@ Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f CONTROL FLOW GRAPH SSA @@ -12,9 +14,9 @@ fn1::@return: scope:[fn1] from fn1 void main() main: scope:[main] from __start::@1 - call *main::f + callexecute *main::f SCREEN[idx] = 'a' - call *main::f + callexecute *main::f SCREEN[idx] = 'a' to:main::@return main::@return: scope:[main] from main @@ -46,8 +48,8 @@ constant void()* main::f = &fn1 Simplifying constant pointer cast (byte*) 1024 Successful SSA optimization PassNCastSimplification -Replacing constant pointer function [2] call fn1 -Replacing constant pointer function [4] call fn1 +Replacing constant pointer function [2] callexecute fn1 +Replacing constant pointer function [4] callexecute fn1 Successful SSA optimization Pass2ConstantCallPointerIdentification Eliminating unused constant main::f Successful SSA optimization PassNEliminateUnusedVars @@ -94,9 +96,9 @@ fn1::@return: scope:[fn1] from fn1 void main() main: scope:[main] from __start::@1 [7] phi() - [8] call fn1 + [8] callexecute fn1 [9] SCREEN[idx] = 'a' - [10] call fn1 + [10] callexecute fn1 [11] SCREEN[idx] = 'a' to:main::@return main::@return: scope:[main] from main @@ -185,13 +187,13 @@ fn1: { } // main main: { - // [8] call fn1 + // [8] callexecute fn1 -- jsr jsr fn1 // [9] SCREEN[idx] = 'a' -- pbuc1_derefidx_vbuz1=vbuc2 lda #'a' ldy.z idx sta SCREEN,y - // [10] call fn1 + // [10] callexecute fn1 -- jsr jsr fn1 // [11] SCREEN[idx] = 'a' -- pbuc1_derefidx_vbuz1=vbuc2 lda #'a' @@ -279,7 +281,7 @@ fn1: { // main main: { // (*f)() - // [8] call fn1 + // [8] callexecute fn1 -- jsr jsr fn1 // SCREEN[idx] = 'a' // [9] SCREEN[idx] = 'a' -- pbuc1_derefidx_vbuz1=vbuc2 @@ -287,7 +289,7 @@ main: { ldy.z idx sta SCREEN,y // (*f)() - // [10] call fn1 + // [10] callexecute fn1 -- jsr jsr fn1 // SCREEN[idx] = 'a' // [11] SCREEN[idx] = 'a' -- pbuc1_derefidx_vbuz1=vbuc2 diff --git a/src/test/ref/function-pointer-noarg-call.cfg b/src/test/ref/function-pointer-noarg-call.cfg index 1603ef52d..72c4c02ca 100644 --- a/src/test/ref/function-pointer-noarg-call.cfg +++ b/src/test/ref/function-pointer-noarg-call.cfg @@ -2,7 +2,7 @@ void main() main: scope:[main] from [0] phi() - [1] call fn1 + [1] callexecute fn1 to:main::@return main::@return: scope:[main] from main [2] return diff --git a/src/test/ref/function-pointer-noarg-call.log b/src/test/ref/function-pointer-noarg-call.log index 71de196bc..86c426675 100644 --- a/src/test/ref/function-pointer-noarg-call.log +++ b/src/test/ref/function-pointer-noarg-call.log @@ -1,3 +1,4 @@ +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f CONTROL FLOW GRAPH SSA @@ -11,7 +12,7 @@ fn1::@return: scope:[fn1] from fn1 void main() main: scope:[main] from __start - call *main::f + callexecute *main::f to:main::@return main::@return: scope:[main] from main return @@ -36,7 +37,7 @@ constant void()* main::f = &fn1 Simplifying constant pointer cast (byte*) 53280 Successful SSA optimization PassNCastSimplification -Replacing constant pointer function [2] call fn1 +Replacing constant pointer function [2] callexecute fn1 Successful SSA optimization Pass2ConstantCallPointerIdentification Eliminating unused constant main::f Successful SSA optimization PassNEliminateUnusedVars @@ -58,7 +59,7 @@ FINAL CONTROL FLOW GRAPH void main() main: scope:[main] from [0] phi() - [1] call fn1 + [1] callexecute fn1 to:main::@return main::@return: scope:[main] from main [2] return @@ -106,7 +107,7 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Code // main main: { - // [1] call fn1 + // [1] callexecute fn1 -- jsr jsr fn1 jmp __breturn // main::@return @@ -161,7 +162,7 @@ Score: 24 // main main: { // (*f)() - // [1] call fn1 + // [1] callexecute fn1 -- jsr jsr fn1 // main::@return // } diff --git a/src/test/ref/function-pointer-param-0.asm b/src/test/ref/function-pointer-param-0.asm new file mode 100644 index 000000000..8c5d729eb --- /dev/null +++ b/src/test/ref/function-pointer-param-0.asm @@ -0,0 +1,105 @@ +// Test function pointers with parameters +// Currently the parameter is not transferred properly + // Commodore 64 PRG executable file +.file [name="function-pointer-param-0.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + .const STACK_BASE = $103 + .label SCREEN = $400 +.segment Code +// fn3(byte register(A) e) +fn3: { + .const OFFSET_STACK_E = 0 + tsx + lda STACK_BASE+OFFSET_STACK_E,x + // SCREEN[e] = 'c' + tay + lda #'c' + sta SCREEN,y + // } + rts +} +// fn2(byte register(A) d) +fn2: { + .const OFFSET_STACK_D = 0 + tsx + lda STACK_BASE+OFFSET_STACK_D,x + // SCREEN[d] = 'b' + tay + lda #'b' + sta SCREEN,y + // } + rts +} +// fn1(byte register(A) c) +fn1: { + .const OFFSET_STACK_C = 0 + tsx + lda STACK_BASE+OFFSET_STACK_C,x + // SCREEN[c] = 'a' + tay + lda #'a' + sta SCREEN,y + // } + rts +} +main: { + .label i = 2 + // A pointer to a function taking a single char param + .label f = 3 + lda #0 + sta.z i + __b1: + // for(char i=0;i<160;i++) + lda.z i + cmp #$a0 + bcc __b2 + // } + rts + __b2: + // i&1 + lda #1 + and.z i + // if((i&1)==0) + cmp #0 + bne __b3 + // fn3(i) + lda.z i + pha + jsr fn3 + pla + __b4: + // for(char i=0;i<160;i++) + inc.z i + jmp __b1 + __b3: + // i&3 + lda #3 + and.z i + // if((i&3)==1) + cmp #1 + beq __b5 + lda #fn2 + sta.z f+1 + jmp __b6 + __b5: + lda #fn1 + sta.z f+1 + __b6: + // (*f)(i) + lda.z i + pha + jsr bi_f + pla + jmp __b4 + bi_f: + jmp (f) +} diff --git a/src/test/ref/function-pointer-param-0.cfg b/src/test/ref/function-pointer-param-0.cfg new file mode 100644 index 000000000..051b9c72e --- /dev/null +++ b/src/test/ref/function-pointer-param-0.cfg @@ -0,0 +1,64 @@ + +__stackcall void fn3(byte fn3::e) +fn3: scope:[fn3] from + [0] fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) + [1] SCREEN[fn3::e#0] = 'c' + to:fn3::@return +fn3::@return: scope:[fn3] from fn3 + [2] return + to:@return + +__stackcall void fn2(byte fn2::d) +fn2: scope:[fn2] from + [3] fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) + [4] SCREEN[fn2::d#0] = 'b' + to:fn2::@return +fn2::@return: scope:[fn2] from fn2 + [5] return + to:@return + +__stackcall void fn1(byte fn1::c) +fn1: scope:[fn1] from + [6] fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) + [7] SCREEN[fn1::c#0] = 'a' + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + [8] return + to:@return + +void main() +main: scope:[main] from + [9] phi() + to:main::@1 +main::@1: scope:[main] from main main::@4 + [10] main::i#2 = phi( main/0, main::@4/main::i#1 ) + [11] if(main::i#2<$a0) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@1 + [12] return + to:@return +main::@2: scope:[main] from main::@1 + [13] main::$1 = main::i#2 & 1 + [14] if(main::$1!=0) goto main::@3 + to:main::@7 +main::@7: scope:[main] from main::@2 + [15] stackpush(byte) = main::i#2 + [16] callexecute fn3 + sideeffect stackpullbytes(1) + to:main::@4 +main::@4: scope:[main] from main::@6 main::@7 + [18] main::i#1 = ++ main::i#2 + to:main::@1 +main::@3: scope:[main] from main::@2 + [19] main::$5 = main::i#2 & 3 + [20] if(main::$5==1) goto main::@5 + to:main::@6 +main::@5: scope:[main] from main::@3 + [21] phi() + to:main::@6 +main::@6: scope:[main] from main::@3 main::@5 + [22] main::f#3 = phi( main::@5/&fn1, main::@3/&fn2 ) + [23] stackpush(byte) = main::i#2 + [24] callexecute *main::f#3 + sideeffect stackpullbytes(1) + to:main::@4 diff --git a/src/test/ref/function-pointer-param-0.log b/src/test/ref/function-pointer-param-0.log new file mode 100644 index 000000000..ecea68171 --- /dev/null +++ b/src/test/ref/function-pointer-param-0.log @@ -0,0 +1,758 @@ +Resolved forward reference fn1 to void fn1(byte fn1::c) +Resolved forward reference fn2 to void fn2(byte fn2::d) +Setting inferred __stackcall on procedure affected by address-of __stackcall void fn1(byte fn1::c) caused by statement main::f = &fn1 +Setting inferred __stackcall on procedure affected by address-of __stackcall void fn2(byte fn2::d) caused by statement main::f = &fn2 +Adding parameter assignment in __stackcall procedure fn1::c = param(fn1::c) +Adding parameter assignment in __stackcall procedure fn2::d = param(fn2::d) +Adding parameter assignment in __stackcall procedure fn3::e = param(fn3::e) +Calling convention __stackcall adding prepare/execute/finalize for call fn3 main::i +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f main::i +Calling convention STACK_CALL replacing param(fn1::c) with stackidx(byte,fn1::OFFSET_STACK_C) +Calling convention STACK_CALL replacing param(fn2::d) with stackidx(byte,fn2::OFFSET_STACK_D) +Calling convention STACK_CALL replacing param(fn3::e) with stackidx(byte,fn3::OFFSET_STACK_E) +Calling convention STACK_CALL adding stack push stackpush(byte) = main::i +Calling convention STACK_CALL adding stack push stackpush(byte) = main::i + +CONTROL FLOW GRAPH SSA + +void main() +main: scope:[main] from __start + main::f#0 = (void(byte)*) 0 + main::i#0 = 0 + to:main::@1 +main::@1: scope:[main] from main main::@4 + main::i#2 = phi( main/main::i#0, main::@4/main::i#1 ) + main::$0 = main::i#2 < $a0 + if(main::$0) goto main::@2 + to:main::@return +main::@2: scope:[main] from main::@1 + main::i#3 = phi( main::@1/main::i#2 ) + main::$1 = main::i#3 & 1 + main::$2 = main::$1 == 0 + main::$3 = ! main::$2 + if(main::$3) goto main::@3 + to:main::@7 +main::@3: scope:[main] from main::@2 + main::i#4 = phi( main::@2/main::i#3 ) + main::$5 = main::i#4 & 3 + main::$6 = main::$5 == 1 + if(main::$6) goto main::@5 + to:main::@8 +main::@7: scope:[main] from main::@2 + main::i#5 = phi( main::@2/main::i#3 ) + stackpush(byte) = main::i#5 + callexecute fn3 + sideeffect stackpullbytes(1) + to:main::@4 +main::@4: scope:[main] from main::@6 main::@7 + main::i#6 = phi( main::@6/main::i#7, main::@7/main::i#5 ) + main::i#1 = ++ main::i#6 + to:main::@1 +main::@5: scope:[main] from main::@3 + main::i#8 = phi( main::@3/main::i#4 ) + main::f#1 = &fn1 + to:main::@6 +main::@8: scope:[main] from main::@3 + main::i#9 = phi( main::@3/main::i#4 ) + main::f#2 = &fn2 + to:main::@6 +main::@6: scope:[main] from main::@5 main::@8 + main::f#3 = phi( main::@5/main::f#1, main::@8/main::f#2 ) + main::i#7 = phi( main::@5/main::i#8, main::@8/main::i#9 ) + stackpush(byte) = main::i#7 + callexecute *main::f#3 + sideeffect stackpullbytes(1) + to:main::@4 +main::@return: scope:[main] from main::@1 + return + to:@return + +__stackcall void fn1(byte fn1::c) +fn1: scope:[fn1] from + fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) + SCREEN[fn1::c#0] = 'a' + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + return + to:@return + +__stackcall void fn2(byte fn2::d) +fn2: scope:[fn2] from + fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) + SCREEN[fn2::d#0] = 'b' + to:fn2::@return +fn2::@return: scope:[fn2] from fn2 + return + to:@return + +__stackcall void fn3(byte fn3::e) +fn3: scope:[fn3] from + fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) + SCREEN[fn3::e#0] = 'c' + to:fn3::@return +fn3::@return: scope:[fn3] from fn3 + return + to:@return + +void __start() +__start: scope:[__start] from + call main + to:__start::@1 +__start::@1: scope:[__start] from __start + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + return + to:@return + +SYMBOL TABLE SSA +constant byte* const SCREEN = (byte*)$400 +constant word STACK_BASE = $103 +void __start() +__stackcall void fn1(byte fn1::c) +constant byte fn1::OFFSET_STACK_C = 0 +byte fn1::c +byte fn1::c#0 +__stackcall void fn2(byte fn2::d) +constant byte fn2::OFFSET_STACK_D = 0 +byte fn2::d +byte fn2::d#0 +__stackcall void fn3(byte fn3::e) +constant byte fn3::OFFSET_STACK_E = 0 +byte fn3::e +byte fn3::e#0 +void main() +bool~ main::$0 +number~ main::$1 +bool~ main::$2 +bool~ main::$3 +number~ main::$5 +bool~ main::$6 +void(byte)* main::f +void(byte)* main::f#0 +void(byte)* main::f#1 +void(byte)* main::f#2 +void(byte)* main::f#3 +byte main::i +byte main::i#0 +byte main::i#1 +byte main::i#2 +byte main::i#3 +byte main::i#4 +byte main::i#5 +byte main::i#6 +byte main::i#7 +byte main::i#8 +byte main::i#9 + +Adding number conversion cast (unumber) $a0 in main::$0 = main::i#2 < $a0 +Adding number conversion cast (unumber) 1 in main::$1 = main::i#3 & 1 +Adding number conversion cast (unumber) main::$1 in main::$1 = main::i#3 & (unumber)1 +Adding number conversion cast (unumber) 0 in main::$2 = main::$1 == 0 +Adding number conversion cast (unumber) 3 in main::$5 = main::i#4 & 3 +Adding number conversion cast (unumber) main::$5 in main::$5 = main::i#4 & (unumber)3 +Adding number conversion cast (unumber) 1 in main::$6 = main::$5 == 1 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast $a0 +Simplifying constant integer cast 1 +Simplifying constant integer cast 0 +Simplifying constant integer cast 3 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) $a0 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 3 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to byte in main::$1 = main::i#3 & 1 +Inferred type updated to byte in main::$5 = main::i#4 & 3 +Inversing boolean not [8] main::$3 = main::$1 != 0 from [7] main::$2 = main::$1 == 0 +Successful SSA optimization Pass2UnaryNotSimplification +Alias main::i#2 = main::i#3 main::i#4 main::i#5 main::i#8 main::i#9 +Successful SSA optimization Pass2AliasElimination +Alias main::i#2 = main::i#7 +Successful SSA optimization Pass2AliasElimination +Alias main::i#2 = main::i#6 +Successful SSA optimization Pass2AliasElimination +Simple Condition main::$0 [4] if(main::i#2<$a0) goto main::@2 +Simple Condition main::$3 [7] if(main::$1!=0) goto main::@3 +Simple Condition main::$6 [10] if(main::$5==1) goto main::@5 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant main::f#0 = (void(byte)*) 0 +Constant main::i#0 = 0 +Constant main::f#1 = &fn1 +Constant main::f#2 = &fn2 +Successful SSA optimization Pass2ConstantIdentification +Eliminating unused constant main::f#0 +Successful SSA optimization PassNEliminateUnusedVars +Removing unused procedure __start +Removing unused procedure block __start +Removing unused procedure block __start::@1 +Removing unused procedure block __start::@return +Successful SSA optimization PassNEliminateEmptyStart +Inlining constant with var siblings main::i#0 +Inlining constant with var siblings main::f#1 +Inlining constant with var siblings main::f#2 +Constant inlined main::i#0 = 0 +Constant inlined main::f#2 = &fn2 +Constant inlined main::f#1 = &fn1 +Successful SSA optimization Pass2ConstantInlining +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@8 +Adding NOP phi() at start of main::@5 +CALL GRAPH +Calls in [main] to fn3:16 null:25 + +Created 2 initial phi equivalence classes +Coalesced [19] main::i#10 = main::i#1 +Coalesced down to 2 phi equivalence classes +Culled Empty Block label main::@8 +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@5 + +FINAL CONTROL FLOW GRAPH + +__stackcall void fn3(byte fn3::e) +fn3: scope:[fn3] from + [0] fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) + [1] SCREEN[fn3::e#0] = 'c' + to:fn3::@return +fn3::@return: scope:[fn3] from fn3 + [2] return + to:@return + +__stackcall void fn2(byte fn2::d) +fn2: scope:[fn2] from + [3] fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) + [4] SCREEN[fn2::d#0] = 'b' + to:fn2::@return +fn2::@return: scope:[fn2] from fn2 + [5] return + to:@return + +__stackcall void fn1(byte fn1::c) +fn1: scope:[fn1] from + [6] fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) + [7] SCREEN[fn1::c#0] = 'a' + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + [8] return + to:@return + +void main() +main: scope:[main] from + [9] phi() + to:main::@1 +main::@1: scope:[main] from main main::@4 + [10] main::i#2 = phi( main/0, main::@4/main::i#1 ) + [11] if(main::i#2<$a0) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@1 + [12] return + to:@return +main::@2: scope:[main] from main::@1 + [13] main::$1 = main::i#2 & 1 + [14] if(main::$1!=0) goto main::@3 + to:main::@7 +main::@7: scope:[main] from main::@2 + [15] stackpush(byte) = main::i#2 + [16] callexecute fn3 + sideeffect stackpullbytes(1) + to:main::@4 +main::@4: scope:[main] from main::@6 main::@7 + [18] main::i#1 = ++ main::i#2 + to:main::@1 +main::@3: scope:[main] from main::@2 + [19] main::$5 = main::i#2 & 3 + [20] if(main::$5==1) goto main::@5 + to:main::@6 +main::@5: scope:[main] from main::@3 + [21] phi() + to:main::@6 +main::@6: scope:[main] from main::@3 main::@5 + [22] main::f#3 = phi( main::@5/&fn1, main::@3/&fn2 ) + [23] stackpush(byte) = main::i#2 + [24] callexecute *main::f#3 + sideeffect stackpullbytes(1) + to:main::@4 + +null depth in calling loop Loop head: main::@1 tails: main::@4 blocks: main::@4 main::@6 main::@7 main::@3 main::@5 main::@2 main::@1 in scope fn3 + +VARIABLE REGISTER WEIGHTS +__stackcall void fn1(byte fn1::c) +byte fn1::c +byte fn1::c#0 4.0 +__stackcall void fn2(byte fn2::d) +byte fn2::d +byte fn2::d#0 4.0 +__stackcall void fn3(byte fn3::e) +byte fn3::e +byte fn3::e#0 202.0 +void main() +byte~ main::$1 22.0 +byte~ main::$5 22.0 +void(byte)* main::f +void(byte)* main::f#3 +byte main::i +byte main::i#1 22.0 +byte main::i#2 5.9230769230769225 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ main::f#3 ] +Added variable fn3::e#0 to live range equivalence class [ fn3::e#0 ] +Added variable fn2::d#0 to live range equivalence class [ fn2::d#0 ] +Added variable fn1::c#0 to live range equivalence class [ fn1::c#0 ] +Added variable main::$1 to live range equivalence class [ main::$1 ] +Added variable main::$5 to live range equivalence class [ main::$5 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::f#3 ] +[ fn3::e#0 ] +[ fn2::d#0 ] +[ fn1::c#0 ] +[ main::$1 ] +[ main::$5 ] +Allocated zp[1]:2 [ main::i#2 main::i#1 ] +Allocated zp[2]:3 [ main::f#3 ] +Allocated zp[1]:5 [ fn3::e#0 ] +Allocated zp[1]:6 [ fn2::d#0 ] +Allocated zp[1]:7 [ fn1::c#0 ] +Allocated zp[1]:8 [ main::$1 ] +Allocated zp[1]:9 [ main::$5 ] +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) [ fn3::e#0 ] ( fn3:16 [ main::i#2 fn3::e#0 ] { } ) always clobbers reg byte a reg byte x +Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Statement [1] SCREEN[fn3::e#0] = 'c' [ ] ( fn3:16 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [3] fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) [ fn2::d#0 ] ( [ fn2::d#0 ] { } ) always clobbers reg byte a reg byte x +Statement [4] SCREEN[fn2::d#0] = 'b' [ ] ( [ ] { } ) always clobbers reg byte a +Statement [6] fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) [ fn1::c#0 ] ( [ fn1::c#0 ] { } ) always clobbers reg byte a reg byte x +Statement [7] SCREEN[fn1::c#0] = 'a' [ ] ( [ ] { } ) always clobbers reg byte a +Statement [13] main::$1 = main::i#2 & 1 [ main::i#2 main::$1 ] ( [ main::i#2 main::$1 ] { } ) always clobbers reg byte a +Statement [15] stackpush(byte) = main::i#2 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a +Statement sideeffect stackpullbytes(1) always clobbers reg byte a +Statement [19] main::$5 = main::i#2 & 3 [ main::i#2 main::$5 ] ( [ main::i#2 main::$5 ] { } ) always clobbers reg byte a +Statement [23] stackpush(byte) = main::i#2 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [24] callexecute *main::f#3 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y +Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Statement sideeffect stackpullbytes(1) always clobbers reg byte a +Statement [0] fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) [ fn3::e#0 ] ( fn3:16 [ main::i#2 fn3::e#0 ] { } ) always clobbers reg byte a reg byte x +Statement [1] SCREEN[fn3::e#0] = 'c' [ ] ( fn3:16 [ main::i#2 ] { } ) always clobbers reg byte a +Statement [3] fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) [ fn2::d#0 ] ( [ fn2::d#0 ] { } ) always clobbers reg byte a reg byte x +Statement [4] SCREEN[fn2::d#0] = 'b' [ ] ( [ ] { } ) always clobbers reg byte a +Statement [6] fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) [ fn1::c#0 ] ( [ fn1::c#0 ] { } ) always clobbers reg byte a reg byte x +Statement [7] SCREEN[fn1::c#0] = 'a' [ ] ( [ ] { } ) always clobbers reg byte a +Statement [11] if(main::i#2<$a0) goto main::@2 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a +Statement [13] main::$1 = main::i#2 & 1 [ main::i#2 main::$1 ] ( [ main::i#2 main::$1 ] { } ) always clobbers reg byte a +Statement [15] stackpush(byte) = main::i#2 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a +Statement sideeffect stackpullbytes(1) always clobbers reg byte a +Statement [19] main::$5 = main::i#2 & 3 [ main::i#2 main::$5 ] ( [ main::i#2 main::$5 ] { } ) always clobbers reg byte a +Statement [23] stackpush(byte) = main::i#2 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [24] callexecute *main::f#3 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement sideeffect stackpullbytes(1) always clobbers reg byte a +Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , +Potential registers zp[2]:3 [ main::f#3 ] : zp[2]:3 , +Potential registers zp[1]:5 [ fn3::e#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:6 [ fn2::d#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:7 [ fn1::c#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:8 [ main::$1 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:9 [ main::$5 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [fn3] 202: zp[1]:5 [ fn3::e#0 ] +Uplift Scope [main] 27.92: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:8 [ main::$1 ] 22: zp[1]:9 [ main::$5 ] 0: zp[2]:3 [ main::f#3 ] +Uplift Scope [fn1] 4: zp[1]:7 [ fn1::c#0 ] +Uplift Scope [fn2] 4: zp[1]:6 [ fn2::d#0 ] +Uplift Scope [] + +Uplifting [fn3] best 1391 combination reg byte a [ fn3::e#0 ] +Uplifting [main] best 1291 combination zp[1]:2 [ main::i#2 main::i#1 ] reg byte a [ main::$1 ] reg byte a [ main::$5 ] zp[2]:3 [ main::f#3 ] +Uplifting [fn1] best 1287 combination reg byte a [ fn1::c#0 ] +Uplifting [fn2] best 1283 combination reg byte a [ fn2::d#0 ] +Uplifting [] best 1283 combination +Attempting to uplift remaining variables inzp[1]:2 [ main::i#2 main::i#1 ] +Uplifting [main] best 1283 combination zp[1]:2 [ main::i#2 main::i#1 ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Test function pointers with parameters +// Currently the parameter is not transferred properly + // Upstart + // Commodore 64 PRG executable file +.file [name="function-pointer-param-0.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + // Global Constants & labels + .const STACK_BASE = $103 + .label SCREEN = $400 +.segment Code + // fn3 +// fn3(byte register(A) e) +fn3: { + .const OFFSET_STACK_E = 0 + // [0] fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) -- vbuaa=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_E,x + // [1] SCREEN[fn3::e#0] = 'c' -- pbuc1_derefidx_vbuaa=vbuc2 + tay + lda #'c' + sta SCREEN,y + jmp __breturn + // fn3::@return + __breturn: + // [2] return + rts +} + // fn2 +// fn2(byte register(A) d) +fn2: { + .const OFFSET_STACK_D = 0 + // [3] fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) -- vbuaa=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_D,x + // [4] SCREEN[fn2::d#0] = 'b' -- pbuc1_derefidx_vbuaa=vbuc2 + tay + lda #'b' + sta SCREEN,y + jmp __breturn + // fn2::@return + __breturn: + // [5] return + rts +} + // fn1 +// fn1(byte register(A) c) +fn1: { + .const OFFSET_STACK_C = 0 + // [6] fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) -- vbuaa=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_C,x + // [7] SCREEN[fn1::c#0] = 'a' -- pbuc1_derefidx_vbuaa=vbuc2 + tay + lda #'a' + sta SCREEN,y + jmp __breturn + // fn1::@return + __breturn: + // [8] return + rts +} + // main +main: { + .label i = 2 + // A pointer to a function taking a single char param + .label f = 3 + // [10] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + // [10] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z i + jmp __b1 + // main::@1 + __b1: + // [11] if(main::i#2<$a0) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z i + cmp #$a0 + bcc __b2 + jmp __breturn + // main::@return + __breturn: + // [12] return + rts + // main::@2 + __b2: + // [13] main::$1 = main::i#2 & 1 -- vbuaa=vbuz1_band_vbuc1 + lda #1 + and.z i + // [14] if(main::$1!=0) goto main::@3 -- vbuaa_neq_0_then_la1 + cmp #0 + bne __b3 + jmp __b7 + // main::@7 + __b7: + // [15] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + lda.z i + pha + // [16] callexecute fn3 -- jsr + jsr fn3 + // sideeffect stackpullbytes(1) -- _stackpullbyte_1 + pla + jmp __b4 + // main::@4 + __b4: + // [18] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // [10] phi from main::@4 to main::@1 [phi:main::@4->main::@1] + __b1_from___b4: + // [10] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy + jmp __b1 + // main::@3 + __b3: + // [19] main::$5 = main::i#2 & 3 -- vbuaa=vbuz1_band_vbuc1 + lda #3 + and.z i + // [20] if(main::$5==1) goto main::@5 -- vbuaa_eq_vbuc1_then_la1 + cmp #1 + beq __b5_from___b3 + // [22] phi from main::@3 to main::@6 [phi:main::@3->main::@6] + __b6_from___b3: + // [22] phi main::f#3 = &fn2 [phi:main::@3->main::@6#0] -- pprz1=pprc1 + lda #fn2 + sta.z f+1 + jmp __b6 + // [21] phi from main::@3 to main::@5 [phi:main::@3->main::@5] + __b5_from___b3: + jmp __b5 + // main::@5 + __b5: + // [22] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + __b6_from___b5: + // [22] phi main::f#3 = &fn1 [phi:main::@5->main::@6#0] -- pprz1=pprc1 + lda #fn1 + sta.z f+1 + jmp __b6 + // main::@6 + __b6: + // [23] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + lda.z i + pha + // [24] callexecute *main::f#3 + jsr bi_f + // sideeffect stackpullbytes(1) -- _stackpullbyte_1 + pla + jmp __b4 + bi_f: + jmp (f) +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b7 +Removing instruction jmp __b4 +Removing instruction jmp __b5 +Removing instruction jmp __b6 +Succesful ASM optimization Pass5NextJumpElimination +Replacing label __b5_from___b3 with __b5 +Removing instruction __b5_from___b3: +Removing instruction __b6_from___b5: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __b1_from_main: +Removing instruction __breturn: +Removing instruction __b7: +Removing instruction __b1_from___b4: +Removing instruction __b6_from___b3: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +constant byte* const SCREEN = (byte*) 1024 +constant word STACK_BASE = $103 +__stackcall void fn1(byte fn1::c) +constant byte fn1::OFFSET_STACK_C = 0 +byte fn1::c +byte fn1::c#0 reg byte a 4.0 +__stackcall void fn2(byte fn2::d) +constant byte fn2::OFFSET_STACK_D = 0 +byte fn2::d +byte fn2::d#0 reg byte a 4.0 +__stackcall void fn3(byte fn3::e) +constant byte fn3::OFFSET_STACK_E = 0 +byte fn3::e +byte fn3::e#0 reg byte a 202.0 +void main() +byte~ main::$1 reg byte a 22.0 +byte~ main::$5 reg byte a 22.0 +void(byte)* main::f +void(byte)* main::f#3 f zp[2]:3 +byte main::i +byte main::i#1 i zp[1]:2 22.0 +byte main::i#2 i zp[1]:2 5.9230769230769225 + +zp[1]:2 [ main::i#2 main::i#1 ] +zp[2]:3 [ main::f#3 ] +reg byte a [ fn3::e#0 ] +reg byte a [ fn2::d#0 ] +reg byte a [ fn1::c#0 ] +reg byte a [ main::$1 ] +reg byte a [ main::$5 ] + + +FINAL ASSEMBLER +Score: 1094 + + // File Comments +// Test function pointers with parameters +// Currently the parameter is not transferred properly + // Upstart + // Commodore 64 PRG executable file +.file [name="function-pointer-param-0.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + // Global Constants & labels + .const STACK_BASE = $103 + .label SCREEN = $400 +.segment Code + // fn3 +// fn3(byte register(A) e) +fn3: { + .const OFFSET_STACK_E = 0 + // [0] fn3::e#0 = stackidx(byte,fn3::OFFSET_STACK_E) -- vbuaa=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_E,x + // SCREEN[e] = 'c' + // [1] SCREEN[fn3::e#0] = 'c' -- pbuc1_derefidx_vbuaa=vbuc2 + tay + lda #'c' + sta SCREEN,y + // fn3::@return + // } + // [2] return + rts +} + // fn2 +// fn2(byte register(A) d) +fn2: { + .const OFFSET_STACK_D = 0 + // [3] fn2::d#0 = stackidx(byte,fn2::OFFSET_STACK_D) -- vbuaa=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_D,x + // SCREEN[d] = 'b' + // [4] SCREEN[fn2::d#0] = 'b' -- pbuc1_derefidx_vbuaa=vbuc2 + tay + lda #'b' + sta SCREEN,y + // fn2::@return + // } + // [5] return + rts +} + // fn1 +// fn1(byte register(A) c) +fn1: { + .const OFFSET_STACK_C = 0 + // [6] fn1::c#0 = stackidx(byte,fn1::OFFSET_STACK_C) -- vbuaa=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_C,x + // SCREEN[c] = 'a' + // [7] SCREEN[fn1::c#0] = 'a' -- pbuc1_derefidx_vbuaa=vbuc2 + tay + lda #'a' + sta SCREEN,y + // fn1::@return + // } + // [8] return + rts +} + // main +main: { + .label i = 2 + // A pointer to a function taking a single char param + .label f = 3 + // [10] phi from main to main::@1 [phi:main->main::@1] + // [10] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z i + // main::@1 + __b1: + // for(char i=0;i<160;i++) + // [11] if(main::i#2<$a0) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z i + cmp #$a0 + bcc __b2 + // main::@return + // } + // [12] return + rts + // main::@2 + __b2: + // i&1 + // [13] main::$1 = main::i#2 & 1 -- vbuaa=vbuz1_band_vbuc1 + lda #1 + and.z i + // if((i&1)==0) + // [14] if(main::$1!=0) goto main::@3 -- vbuaa_neq_0_then_la1 + cmp #0 + bne __b3 + // main::@7 + // fn3(i) + // [15] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + lda.z i + pha + // [16] callexecute fn3 -- jsr + jsr fn3 + // sideeffect stackpullbytes(1) -- _stackpullbyte_1 + pla + // main::@4 + __b4: + // for(char i=0;i<160;i++) + // [18] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // [10] phi from main::@4 to main::@1 [phi:main::@4->main::@1] + // [10] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy + jmp __b1 + // main::@3 + __b3: + // i&3 + // [19] main::$5 = main::i#2 & 3 -- vbuaa=vbuz1_band_vbuc1 + lda #3 + and.z i + // if((i&3)==1) + // [20] if(main::$5==1) goto main::@5 -- vbuaa_eq_vbuc1_then_la1 + cmp #1 + beq __b5 + // [22] phi from main::@3 to main::@6 [phi:main::@3->main::@6] + // [22] phi main::f#3 = &fn2 [phi:main::@3->main::@6#0] -- pprz1=pprc1 + lda #fn2 + sta.z f+1 + jmp __b6 + // [21] phi from main::@3 to main::@5 [phi:main::@3->main::@5] + // main::@5 + __b5: + // [22] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + // [22] phi main::f#3 = &fn1 [phi:main::@5->main::@6#0] -- pprz1=pprc1 + lda #fn1 + sta.z f+1 + // main::@6 + __b6: + // (*f)(i) + // [23] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + lda.z i + pha + // [24] callexecute *main::f#3 + jsr bi_f + // sideeffect stackpullbytes(1) -- _stackpullbyte_1 + pla + jmp __b4 + bi_f: + jmp (f) +} + // File Data + diff --git a/src/test/ref/function-pointer-param-0.sym b/src/test/ref/function-pointer-param-0.sym new file mode 100644 index 000000000..e7ffb32da --- /dev/null +++ b/src/test/ref/function-pointer-param-0.sym @@ -0,0 +1,30 @@ +constant byte* const SCREEN = (byte*) 1024 +constant word STACK_BASE = $103 +__stackcall void fn1(byte fn1::c) +constant byte fn1::OFFSET_STACK_C = 0 +byte fn1::c +byte fn1::c#0 reg byte a 4.0 +__stackcall void fn2(byte fn2::d) +constant byte fn2::OFFSET_STACK_D = 0 +byte fn2::d +byte fn2::d#0 reg byte a 4.0 +__stackcall void fn3(byte fn3::e) +constant byte fn3::OFFSET_STACK_E = 0 +byte fn3::e +byte fn3::e#0 reg byte a 202.0 +void main() +byte~ main::$1 reg byte a 22.0 +byte~ main::$5 reg byte a 22.0 +void(byte)* main::f +void(byte)* main::f#3 f zp[2]:3 +byte main::i +byte main::i#1 i zp[1]:2 22.0 +byte main::i#2 i zp[1]:2 5.9230769230769225 + +zp[1]:2 [ main::i#2 main::i#1 ] +zp[2]:3 [ main::f#3 ] +reg byte a [ fn3::e#0 ] +reg byte a [ fn2::d#0 ] +reg byte a [ fn1::c#0 ] +reg byte a [ main::$1 ] +reg byte a [ main::$5 ] diff --git a/src/test/ref/function-pointer-param-workaround.cfg b/src/test/ref/function-pointer-param-workaround.cfg index 7317f3c15..5a7cd3415 100644 --- a/src/test/ref/function-pointer-param-workaround.cfg +++ b/src/test/ref/function-pointer-param-workaround.cfg @@ -79,6 +79,6 @@ main::@3: scope:[main] from main::@2 asm { ldaparam_char pha } [44] main::$3 = main::j#2 << 1 [45] main::f#0 = main::fns[main::$3] - [46] call *main::f#0 + [46] callexecute *main::f#0 [47] main::j#1 = ++ main::j#2 to:main::@2 diff --git a/src/test/ref/function-pointer-param-workaround.log b/src/test/ref/function-pointer-param-workaround.log index 1efa056fe..ac7815e7b 100644 --- a/src/test/ref/function-pointer-param-workaround.log +++ b/src/test/ref/function-pointer-param-workaround.log @@ -2,6 +2,7 @@ Setting inferred volatile on symbol affected by address-of: fn1::param_char in a Setting inferred volatile on symbol affected by address-of: fn2::param_char in asm { pla staparam_char } Setting inferred volatile on symbol affected by address-of: main::param_char in asm { ldaparam_char pha } Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *main::f CONTROL FLOW GRAPH SSA @@ -72,7 +73,7 @@ main::@4: scope:[main] from main::@3 asm { ldaparam_char pha } main::$3 = main::j#3 * SIZEOF_POINTER main::f#0 = main::fns[main::$3] - call *main::f#0 + callexecute *main::f#0 main::j#1 = ++ main::j#3 to:main::@3 main::@5: scope:[main] from main::@3 @@ -203,6 +204,7 @@ Adding NOP phi() at start of main Adding NOP phi() at start of main::@2 CALL GRAPH Calls in [__start] to main:4 +Calls in [main] to null:49 Created 2 initial phi equivalence classes Coalesced [41] main::i#7 = main::i#1 @@ -299,7 +301,7 @@ main::@3: scope:[main] from main::@2 asm { ldaparam_char pha } [44] main::$3 = main::j#2 << 1 [45] main::f#0 = main::fns[main::$3] - [46] call *main::f#0 + [46] callexecute *main::f#0 [47] main::j#1 = ++ main::j#2 to:main::@2 @@ -325,13 +327,13 @@ volatile byte idx2 loadstore 1.272727272727273 void main() byte~ main::$3 2002.0 void()* main::f -void()* main::f#0 1001.0 +void()* main::f#0 10010.0 byte main::i byte main::i#1 202.0 -byte main::i#2 100.3076923076923 +byte main::i#2 186.28571428571428 byte main::j byte main::j#1 2002.0 -byte main::j#2 500.5 +byte main::j#2 625.625 volatile byte main::param_char loadstore 1501.5 Initial phi equivalence classes @@ -411,9 +413,9 @@ Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::j#2 main::j#1 ] Statement asm { ldaparam_char pha } always clobbers reg byte a Statement asm { ldaparam_char pha } always clobbers reg byte a -Statement [44] main::$3 = main::j#2 << 1 [ main::i#2 main::j#2 main::$3 ] ( main:4 [ main::i#2 main::j#2 main::$3 ] { } ) always clobbers reg byte a -Statement [45] main::f#0 = main::fns[main::$3] [ main::i#2 main::j#2 main::f#0 ] ( main:4 [ main::i#2 main::j#2 main::f#0 ] { } ) always clobbers reg byte a -Statement [46] call *main::f#0 [ main::i#2 main::j#2 ] ( main:4 [ main::i#2 main::j#2 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [44] main::$3 = main::j#2 << 1 [ main::$3 ] ( main:4 [ main::$3 ] { } ) always clobbers reg byte a +Statement [45] main::f#0 = main::fns[main::$3] [ ] ( main:4 [ ] { } ) always clobbers reg byte a +Statement [46] callexecute *main::f#0 [ main::i#2 main::j#2 ] ( main:4 [ main::i#2 main::j#2 ] { } ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte x as potential for zp[1]:3 [ main::j#2 main::j#1 ] @@ -439,13 +441,13 @@ Statement [29] SCREEN1[idx1] = fn1::c#0 [ idx1 ] ( [ idx1 ] { } ) always clobb Statement [34] if(main::i#2<='p') goto main::@2 [ main::i#2 ] ( main:4 [ main::i#2 ] { } ) always clobbers reg byte a Statement [37] if(main::j#2<2) goto main::@3 [ main::i#2 main::j#2 ] ( main:4 [ main::i#2 main::j#2 ] { } ) always clobbers reg byte a Statement [39] main::param_char = 0 [ main::i#2 main::j#2 ] ( main:4 [ main::i#2 main::j#2 ] { } ) always clobbers reg byte a -Statement [40] main::param_char = main::i#2 [ main::i#2 main::j#2 main::param_char ] ( main:4 [ main::i#2 main::j#2 main::param_char ] { } ) always clobbers reg byte a +Statement [40] main::param_char = main::i#2 [ main::j#2 main::param_char ] ( main:4 [ main::j#2 main::param_char ] { } ) always clobbers reg byte a Statement asm { ldaparam_char pha } always clobbers reg byte a -Statement [42] main::param_char = main::j#2 [ main::i#2 main::j#2 main::param_char ] ( main:4 [ main::i#2 main::j#2 main::param_char ] { } ) always clobbers reg byte a +Statement [42] main::param_char = main::j#2 [ main::j#2 main::param_char ] ( main:4 [ main::j#2 main::param_char ] { } ) always clobbers reg byte a Statement asm { ldaparam_char pha } always clobbers reg byte a -Statement [44] main::$3 = main::j#2 << 1 [ main::i#2 main::j#2 main::$3 ] ( main:4 [ main::i#2 main::j#2 main::$3 ] { } ) always clobbers reg byte a -Statement [45] main::f#0 = main::fns[main::$3] [ main::i#2 main::j#2 main::f#0 ] ( main:4 [ main::i#2 main::j#2 main::f#0 ] { } ) always clobbers reg byte a -Statement [46] call *main::f#0 [ main::i#2 main::j#2 ] ( main:4 [ main::i#2 main::j#2 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [44] main::$3 = main::j#2 << 1 [ main::$3 ] ( main:4 [ main::$3 ] { } ) always clobbers reg byte a +Statement [45] main::f#0 = main::fns[main::$3] [ ] ( main:4 [ ] { } ) always clobbers reg byte a +Statement [46] callexecute *main::f#0 [ main::i#2 main::j#2 ] ( main:4 [ main::i#2 main::j#2 ] { } ) always clobbers reg byte a reg byte x reg byte y Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , Potential registers zp[1]:3 [ main::j#2 main::j#1 ] : zp[1]:3 , Potential registers zp[1]:4 [ idx1 ] : zp[1]:4 , @@ -463,13 +465,13 @@ Potential registers zp[1]:17 [ main::$3 ] : zp[1]:17 , reg byte a , reg byte x , Potential registers zp[2]:18 [ main::f#0 ] : zp[2]:18 , REGISTER UPLIFT SCOPES -Uplift Scope [main] 2,502.5: zp[1]:3 [ main::j#2 main::j#1 ] 2,002: zp[1]:17 [ main::$3 ] 1,501.5: zp[1]:16 [ main::param_char ] 1,001: zp[2]:18 [ main::f#0 ] 302.31: zp[1]:2 [ main::i#2 main::i#1 ] +Uplift Scope [main] 10,010: zp[2]:18 [ main::f#0 ] 2,627.62: zp[1]:3 [ main::j#2 main::j#1 ] 2,002: zp[1]:17 [ main::$3 ] 1,501.5: zp[1]:16 [ main::param_char ] 388.29: zp[1]:2 [ main::i#2 main::i#1 ] Uplift Scope [fn1] 1.2: zp[1]:13 [ fn1::param_char ] 1: zp[1]:14 [ fn1::b#0 ] 1: zp[1]:15 [ fn1::c#0 ] 0.29: zp[2]:11 [ fn1::ret_addr ] Uplift Scope [fn2] 1.2: zp[1]:8 [ fn2::param_char ] 1: zp[1]:9 [ fn2::b#0 ] 1: zp[1]:10 [ fn2::c#0 ] 0.29: zp[2]:6 [ fn2::ret_addr ] Uplift Scope [] 1.27: zp[1]:4 [ idx1 ] 1.27: zp[1]:5 [ idx2 ] Uplift Scope [__start] -Uplifting [main] best 9607 combination zp[1]:3 [ main::j#2 main::j#1 ] reg byte a [ main::$3 ] zp[1]:16 [ main::param_char ] zp[2]:18 [ main::f#0 ] zp[1]:2 [ main::i#2 main::i#1 ] +Uplifting [main] best 9607 combination zp[2]:18 [ main::f#0 ] zp[1]:3 [ main::j#2 main::j#1 ] reg byte a [ main::$3 ] zp[1]:16 [ main::param_char ] zp[1]:2 [ main::i#2 main::i#1 ] Uplifting [fn1] best 9599 combination zp[1]:13 [ fn1::param_char ] reg byte y [ fn1::b#0 ] reg byte x [ fn1::c#0 ] zp[2]:11 [ fn1::ret_addr ] Uplifting [fn2] best 9591 combination zp[1]:8 [ fn2::param_char ] reg byte y [ fn2::b#0 ] reg byte x [ fn2::c#0 ] zp[2]:6 [ fn2::ret_addr ] Uplifting [] best 9591 combination zp[1]:4 [ idx1 ] zp[1]:5 [ idx2 ] @@ -714,7 +716,7 @@ main: { sta.z f lda fns+1,y sta.z f+1 - // [46] call *main::f#0 + // [46] callexecute *main::f#0 jsr bi_f // [47] main::j#1 = ++ main::j#2 -- vbuz1=_inc_vbuz1 inc.z j @@ -792,14 +794,14 @@ volatile byte idx2 loadstore zp[1]:5 1.272727272727273 void main() byte~ main::$3 reg byte a 2002.0 void()* main::f -void()* main::f#0 f zp[2]:13 1001.0 +void()* main::f#0 f zp[2]:13 10010.0 constant void()** main::fns[2] = { &fn1, &fn2 } byte main::i byte main::i#1 i zp[1]:2 202.0 -byte main::i#2 i zp[1]:2 100.3076923076923 +byte main::i#2 i zp[1]:2 186.28571428571428 byte main::j byte main::j#1 j zp[1]:3 2002.0 -byte main::j#2 j zp[1]:3 500.5 +byte main::j#2 j zp[1]:3 625.625 volatile byte main::param_char loadstore zp[1]:12 1501.5 zp[1]:2 [ main::i#2 main::i#1 ] @@ -1041,7 +1043,7 @@ main: { lda fns+1,y sta.z f+1 // (*f)() - // [46] call *main::f#0 + // [46] callexecute *main::f#0 jsr bi_f // for(char j=0;j<2;j++) // [47] main::j#1 = ++ main::j#2 -- vbuz1=_inc_vbuz1 diff --git a/src/test/ref/function-pointer-param-workaround.sym b/src/test/ref/function-pointer-param-workaround.sym index a6b4919ea..f540320e7 100644 --- a/src/test/ref/function-pointer-param-workaround.sym +++ b/src/test/ref/function-pointer-param-workaround.sym @@ -20,14 +20,14 @@ volatile byte idx2 loadstore zp[1]:5 1.272727272727273 void main() byte~ main::$3 reg byte a 2002.0 void()* main::f -void()* main::f#0 f zp[2]:13 1001.0 +void()* main::f#0 f zp[2]:13 10010.0 constant void()** main::fns[2] = { &fn1, &fn2 } byte main::i byte main::i#1 i zp[1]:2 202.0 -byte main::i#2 i zp[1]:2 100.3076923076923 +byte main::i#2 i zp[1]:2 186.28571428571428 byte main::j byte main::j#1 j zp[1]:3 2002.0 -byte main::j#2 j zp[1]:3 500.5 +byte main::j#2 j zp[1]:3 625.625 volatile byte main::param_char loadstore zp[1]:12 1501.5 zp[1]:2 [ main::i#2 main::i#1 ] diff --git a/src/test/ref/function-pointer-return-1.asm b/src/test/ref/function-pointer-return-1.asm new file mode 100644 index 000000000..8056d2b74 --- /dev/null +++ b/src/test/ref/function-pointer-return-1.asm @@ -0,0 +1,71 @@ +// Tests calling functions pointer with no parameter and a return value + // Commodore 64 PRG executable file +.file [name="function-pointer-return-1.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + .const STACK_BASE = $103 +.segment Code +fn2: { + .const OFFSET_STACK_RETURN_0 = 0 + .label BG_COLOR = $d021 + // (*BG_COLOR)++; + inc BG_COLOR + // return *BG_COLOR; + lda BG_COLOR + // } + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + rts +} +fn1: { + .const OFFSET_STACK_RETURN_0 = 0 + .label BORDER_COLOR = $d020 + // (*BORDER_COLOR)++; + inc BORDER_COLOR + // return *BORDER_COLOR; + lda BORDER_COLOR + // } + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + rts +} +main: { + .label SCREEN = $400 + .label i = 2 + .label f = 3 + lda #0 + sta.z i + __b1: + // ++i; + inc.z i + // i&1 + lda #1 + and.z i + // if((i&1)==0) + cmp #0 + beq __b2 + lda #fn2 + sta.z f+1 + jmp __b3 + __b2: + lda #fn1 + sta.z f+1 + __b3: + // char v = (*f)() + pha + jsr bi_f + pla + // SCREEN[0] = v + sta SCREEN + jmp __b1 + bi_f: + jmp (f) +} diff --git a/src/test/ref/function-pointer-return-1.cfg b/src/test/ref/function-pointer-return-1.cfg new file mode 100644 index 000000000..f7233faed --- /dev/null +++ b/src/test/ref/function-pointer-return-1.cfg @@ -0,0 +1,41 @@ + +__stackcall byte fn2() +fn2: scope:[fn2] from + [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR + [1] fn2::return#0 = *fn2::BG_COLOR + to:fn2::@return +fn2::@return: scope:[fn2] from fn2 + [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 + [3] return + to:@return + +__stackcall byte fn1() +fn1: scope:[fn1] from + [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + [5] fn1::return#0 = *fn1::BORDER_COLOR + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 + [7] return + to:@return + +void main() +main: scope:[main] from + [8] phi() + to:main::@1 +main::@1: scope:[main] from main main::@3 + [9] main::i#2 = phi( main/0, main::@3/main::i#1 ) + [10] main::i#1 = ++ main::i#2 + [11] main::$0 = main::i#1 & 1 + [12] if(main::$0==0) goto main::@2 + to:main::@3 +main::@2: scope:[main] from main::@1 + [13] phi() + to:main::@3 +main::@3: scope:[main] from main::@1 main::@2 + [14] main::f#3 = phi( main::@2/&fn1, main::@1/&fn2 ) + sideeffect stackpushbytes(1) + [16] callexecute *main::f#3 + [17] main::v#0 = stackpull(byte) + [18] *main::SCREEN = main::v#0 + to:main::@1 diff --git a/src/test/ref/function-pointer-return-1.log b/src/test/ref/function-pointer-return-1.log new file mode 100644 index 000000000..1151d221a --- /dev/null +++ b/src/test/ref/function-pointer-return-1.log @@ -0,0 +1,561 @@ +Resolved forward reference fn1 to byte fn1() +Resolved forward reference fn2 to byte fn2() +Setting inferred __stackcall on procedure affected by address-of __stackcall byte fn1() caused by statement main::f = &fn1 +Setting inferred __stackcall on procedure affected by address-of __stackcall byte fn2() caused by statement main::f = &fn2 +Eliminating unused variable with no statement main::$2 +Calling convention STACK_CALL adding prepare/execute/finalize for main::v = call *main::f +Calling convention STACK_CALL adding stack return stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return +Calling convention STACK_CALL adding stack return stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return +Calling convention STACK_CALL adding stack pull main::v = stackpull(byte) + +CONTROL FLOW GRAPH SSA + +void main() +main: scope:[main] from __start + main::f#0 = (byte()*) 0 + main::i#0 = 0 + to:main::@1 +main::@1: scope:[main] from main main::@3 + main::i#2 = phi( main/main::i#0, main::@3/main::i#3 ) + main::i#1 = ++ main::i#2 + main::$0 = main::i#1 & 1 + main::$1 = main::$0 == 0 + if(main::$1) goto main::@2 + to:main::@4 +main::@2: scope:[main] from main::@1 + main::i#4 = phi( main::@1/main::i#1 ) + main::f#1 = &fn1 + to:main::@3 +main::@4: scope:[main] from main::@1 + main::i#5 = phi( main::@1/main::i#1 ) + main::f#2 = &fn2 + to:main::@3 +main::@3: scope:[main] from main::@2 main::@4 + main::i#3 = phi( main::@2/main::i#4, main::@4/main::i#5 ) + main::f#3 = phi( main::@2/main::f#1, main::@4/main::f#2 ) + sideeffect stackpushbytes(1) + callexecute *main::f#3 + main::v#0 = stackpull(byte) + main::SCREEN[0] = main::v#0 + to:main::@1 +main::@return: scope:[main] from + return + to:@return + +__stackcall byte fn1() +fn1: scope:[fn1] from + *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + fn1::return#0 = *fn1::BORDER_COLOR + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + fn1::return#2 = phi( fn1/fn1::return#0 ) + fn1::return#1 = fn1::return#2 + stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#1 + return + to:@return + +__stackcall byte fn2() +fn2: scope:[fn2] from + *fn2::BG_COLOR = ++ *fn2::BG_COLOR + fn2::return#0 = *fn2::BG_COLOR + to:fn2::@return +fn2::@return: scope:[fn2] from fn2 + fn2::return#2 = phi( fn2/fn2::return#0 ) + fn2::return#1 = fn2::return#2 + stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#1 + return + to:@return + +void __start() +__start: scope:[__start] from + call main + to:__start::@1 +__start::@1: scope:[__start] from __start + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + return + to:@return + +SYMBOL TABLE SSA +constant word STACK_BASE = $103 +void __start() +__stackcall byte fn1() +constant byte* const fn1::BORDER_COLOR = (byte*)$d020 +constant byte fn1::OFFSET_STACK_RETURN_0 = 0 +byte fn1::return +byte fn1::return#0 +byte fn1::return#1 +byte fn1::return#2 +__stackcall byte fn2() +constant byte* const fn2::BG_COLOR = (byte*)$d021 +constant byte fn2::OFFSET_STACK_RETURN_0 = 0 +byte fn2::return +byte fn2::return#0 +byte fn2::return#1 +byte fn2::return#2 +void main() +number~ main::$0 +bool~ main::$1 +constant byte* const main::SCREEN = (byte*)$400 +byte()* main::f +byte()* main::f#0 +byte()* main::f#1 +byte()* main::f#2 +byte()* main::f#3 +byte main::i +byte main::i#0 +byte main::i#1 +byte main::i#2 +byte main::i#3 +byte main::i#4 +byte main::i#5 +byte main::v +byte main::v#0 + +Adding number conversion cast (unumber) 1 in main::$0 = main::i#1 & 1 +Adding number conversion cast (unumber) main::$0 in main::$0 = main::i#1 & (unumber)1 +Adding number conversion cast (unumber) 0 in main::$1 = main::$0 == 0 +Adding number conversion cast (unumber) 0 in main::SCREEN[0] = main::v#0 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant pointer cast (byte*) 53280 +Simplifying constant pointer cast (byte*) 53281 +Simplifying constant integer cast 1 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to byte in main::$0 = main::i#1 & 1 +Alias main::i#1 = main::i#4 main::i#5 +Alias fn1::return#0 = fn1::return#2 fn1::return#1 +Alias fn2::return#0 = fn2::return#2 fn2::return#1 +Successful SSA optimization Pass2AliasElimination +Alias main::i#1 = main::i#3 +Successful SSA optimization Pass2AliasElimination +Simple Condition main::$1 [6] if(main::$0==0) goto main::@2 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant main::f#0 = (byte()*) 0 +Constant main::i#0 = 0 +Constant main::f#1 = &fn1 +Constant main::f#2 = &fn2 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero main::SCREEN in [13] main::SCREEN[0] = main::v#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Removing unused block main::@return +Successful SSA optimization Pass2EliminateUnusedBlocks +Eliminating unused constant main::f#0 +Successful SSA optimization PassNEliminateUnusedVars +Removing unused procedure __start +Removing unused procedure block __start +Removing unused procedure block __start::@1 +Removing unused procedure block __start::@return +Successful SSA optimization PassNEliminateEmptyStart +Inlining constant with var siblings main::i#0 +Inlining constant with var siblings main::f#1 +Inlining constant with var siblings main::f#2 +Constant inlined main::i#0 = 0 +Constant inlined main::f#2 = &fn2 +Constant inlined main::f#1 = &fn1 +Successful SSA optimization Pass2ConstantInlining +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@4 +Adding NOP phi() at start of main::@2 +CALL GRAPH +Calls in [main] to null:16 + +Created 2 initial phi equivalence classes +Coalesced [19] main::i#6 = main::i#1 +Coalesced down to 2 phi equivalence classes +Culled Empty Block label main::@4 +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@2 + +FINAL CONTROL FLOW GRAPH + +__stackcall byte fn2() +fn2: scope:[fn2] from + [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR + [1] fn2::return#0 = *fn2::BG_COLOR + to:fn2::@return +fn2::@return: scope:[fn2] from fn2 + [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 + [3] return + to:@return + +__stackcall byte fn1() +fn1: scope:[fn1] from + [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + [5] fn1::return#0 = *fn1::BORDER_COLOR + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 + [7] return + to:@return + +void main() +main: scope:[main] from + [8] phi() + to:main::@1 +main::@1: scope:[main] from main main::@3 + [9] main::i#2 = phi( main/0, main::@3/main::i#1 ) + [10] main::i#1 = ++ main::i#2 + [11] main::$0 = main::i#1 & 1 + [12] if(main::$0==0) goto main::@2 + to:main::@3 +main::@2: scope:[main] from main::@1 + [13] phi() + to:main::@3 +main::@3: scope:[main] from main::@1 main::@2 + [14] main::f#3 = phi( main::@2/&fn1, main::@1/&fn2 ) + sideeffect stackpushbytes(1) + [16] callexecute *main::f#3 + [17] main::v#0 = stackpull(byte) + [18] *main::SCREEN = main::v#0 + to:main::@1 + + +VARIABLE REGISTER WEIGHTS +__stackcall byte fn1() +byte fn1::return +byte fn1::return#0 4.0 +__stackcall byte fn2() +byte fn2::return +byte fn2::return#0 4.0 +void main() +byte~ main::$0 22.0 +byte()* main::f +byte()* main::f#3 +byte main::i +byte main::i#1 8.25 +byte main::i#2 22.0 +byte main::v +byte main::v#0 22.0 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ main::f#3 ] +Added variable fn2::return#0 to live range equivalence class [ fn2::return#0 ] +Added variable fn1::return#0 to live range equivalence class [ fn1::return#0 ] +Added variable main::$0 to live range equivalence class [ main::$0 ] +Added variable main::v#0 to live range equivalence class [ main::v#0 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::f#3 ] +[ fn2::return#0 ] +[ fn1::return#0 ] +[ main::$0 ] +[ main::v#0 ] +Allocated zp[1]:2 [ main::i#2 main::i#1 ] +Allocated zp[2]:3 [ main::f#3 ] +Allocated zp[1]:5 [ fn2::return#0 ] +Allocated zp[1]:6 [ fn1::return#0 ] +Allocated zp[1]:7 [ main::$0 ] +Allocated zp[1]:8 [ main::v#0 ] +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [16] callexecute *main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y +Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Statement [17] main::v#0 = stackpull(byte) [ main::i#1 main::v#0 ] ( [ main::i#1 main::v#0 ] { } ) always clobbers reg byte a +Statement [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [11] main::$0 = main::i#1 & 1 [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a +Statement [16] callexecute *main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [17] main::v#0 = stackpull(byte) [ main::i#1 main::v#0 ] ( [ main::i#1 main::v#0 ] { } ) always clobbers reg byte a +Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , +Potential registers zp[2]:3 [ main::f#3 ] : zp[2]:3 , +Potential registers zp[1]:5 [ fn2::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:6 [ fn1::return#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:7 [ main::$0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:8 [ main::v#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 30.25: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:7 [ main::$0 ] 22: zp[1]:8 [ main::v#0 ] 0: zp[2]:3 [ main::f#3 ] +Uplift Scope [fn1] 4: zp[1]:6 [ fn1::return#0 ] +Uplift Scope [fn2] 4: zp[1]:5 [ fn2::return#0 ] +Uplift Scope [] + +Uplifting [main] best 829 combination zp[1]:2 [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] reg byte a [ main::v#0 ] zp[2]:3 [ main::f#3 ] +Uplifting [fn1] best 823 combination reg byte a [ fn1::return#0 ] +Uplifting [fn2] best 817 combination reg byte a [ fn2::return#0 ] +Uplifting [] best 817 combination +Attempting to uplift remaining variables inzp[1]:2 [ main::i#2 main::i#1 ] +Uplifting [main] best 817 combination zp[1]:2 [ main::i#2 main::i#1 ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Tests calling functions pointer with no parameter and a return value + // Upstart + // Commodore 64 PRG executable file +.file [name="function-pointer-return-1.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + // Global Constants & labels + .const STACK_BASE = $103 +.segment Code + // fn2 +fn2: { + .const OFFSET_STACK_RETURN_0 = 0 + .label BG_COLOR = $d021 + // [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 + inc BG_COLOR + // [1] fn2::return#0 = *fn2::BG_COLOR -- vbuaa=_deref_pbuc1 + lda BG_COLOR + jmp __breturn + // fn2::@return + __breturn: + // [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [3] return + rts +} + // fn1 +fn1: { + .const OFFSET_STACK_RETURN_0 = 0 + .label BORDER_COLOR = $d020 + // [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 + inc BORDER_COLOR + // [5] fn1::return#0 = *fn1::BORDER_COLOR -- vbuaa=_deref_pbuc1 + lda BORDER_COLOR + jmp __breturn + // fn1::@return + __breturn: + // [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [7] return + rts +} + // main +main: { + .label SCREEN = $400 + .label i = 2 + .label f = 3 + // [9] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + // [9] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z i + jmp __b1 + // main::@1 + __b1: + // [10] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // [11] main::$0 = main::i#1 & 1 -- vbuaa=vbuz1_band_vbuc1 + lda #1 + and.z i + // [12] if(main::$0==0) goto main::@2 -- vbuaa_eq_0_then_la1 + cmp #0 + beq __b2_from___b1 + // [14] phi from main::@1 to main::@3 [phi:main::@1->main::@3] + __b3_from___b1: + // [14] phi main::f#3 = &fn2 [phi:main::@1->main::@3#0] -- pprz1=pprc1 + lda #fn2 + sta.z f+1 + jmp __b3 + // [13] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + __b2_from___b1: + jmp __b2 + // main::@2 + __b2: + // [14] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + __b3_from___b2: + // [14] phi main::f#3 = &fn1 [phi:main::@2->main::@3#0] -- pprz1=pprc1 + lda #fn1 + sta.z f+1 + jmp __b3 + // main::@3 + __b3: + // sideeffect stackpushbytes(1) -- _stackpushbyte_1 + pha + // [16] callexecute *main::f#3 + jsr bi_f + // [17] main::v#0 = stackpull(byte) -- vbuaa=_stackpullbyte_ + pla + // [18] *main::SCREEN = main::v#0 -- _deref_pbuc1=vbuaa + sta SCREEN + // [9] phi from main::@3 to main::@1 [phi:main::@3->main::@1] + __b1_from___b3: + // [9] phi main::i#2 = main::i#1 [phi:main::@3->main::@1#0] -- register_copy + jmp __b1 + bi_f: + jmp (f) +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __b2 +Removing instruction jmp __b3 +Succesful ASM optimization Pass5NextJumpElimination +Replacing label __b2_from___b1 with __b2 +Removing instruction __b2_from___b1: +Removing instruction __b3_from___b2: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __b1_from_main: +Removing instruction __b3_from___b1: +Removing instruction __b1_from___b3: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +constant word STACK_BASE = $103 +__stackcall byte fn1() +constant byte* const fn1::BORDER_COLOR = (byte*) 53280 +constant byte fn1::OFFSET_STACK_RETURN_0 = 0 +byte fn1::return +byte fn1::return#0 reg byte a 4.0 +__stackcall byte fn2() +constant byte* const fn2::BG_COLOR = (byte*) 53281 +constant byte fn2::OFFSET_STACK_RETURN_0 = 0 +byte fn2::return +byte fn2::return#0 reg byte a 4.0 +void main() +byte~ main::$0 reg byte a 22.0 +constant byte* const main::SCREEN = (byte*) 1024 +byte()* main::f +byte()* main::f#3 f zp[2]:3 +byte main::i +byte main::i#1 i zp[1]:2 8.25 +byte main::i#2 i zp[1]:2 22.0 +byte main::v +byte main::v#0 reg byte a 22.0 + +zp[1]:2 [ main::i#2 main::i#1 ] +zp[2]:3 [ main::f#3 ] +reg byte a [ fn2::return#0 ] +reg byte a [ fn1::return#0 ] +reg byte a [ main::$0 ] +reg byte a [ main::v#0 ] + + +FINAL ASSEMBLER +Score: 721 + + // File Comments +// Tests calling functions pointer with no parameter and a return value + // Upstart + // Commodore 64 PRG executable file +.file [name="function-pointer-return-1.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + // Global Constants & labels + .const STACK_BASE = $103 +.segment Code + // fn2 +fn2: { + .const OFFSET_STACK_RETURN_0 = 0 + .label BG_COLOR = $d021 + // (*BG_COLOR)++; + // [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 + inc BG_COLOR + // return *BG_COLOR; + // [1] fn2::return#0 = *fn2::BG_COLOR -- vbuaa=_deref_pbuc1 + lda BG_COLOR + // fn2::@return + // } + // [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [3] return + rts +} + // fn1 +fn1: { + .const OFFSET_STACK_RETURN_0 = 0 + .label BORDER_COLOR = $d020 + // (*BORDER_COLOR)++; + // [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 + inc BORDER_COLOR + // return *BORDER_COLOR; + // [5] fn1::return#0 = *fn1::BORDER_COLOR -- vbuaa=_deref_pbuc1 + lda BORDER_COLOR + // fn1::@return + // } + // [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [7] return + rts +} + // main +main: { + .label SCREEN = $400 + .label i = 2 + .label f = 3 + // [9] phi from main to main::@1 [phi:main->main::@1] + // [9] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z i + // main::@1 + __b1: + // ++i; + // [10] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + inc.z i + // i&1 + // [11] main::$0 = main::i#1 & 1 -- vbuaa=vbuz1_band_vbuc1 + lda #1 + and.z i + // if((i&1)==0) + // [12] if(main::$0==0) goto main::@2 -- vbuaa_eq_0_then_la1 + cmp #0 + beq __b2 + // [14] phi from main::@1 to main::@3 [phi:main::@1->main::@3] + // [14] phi main::f#3 = &fn2 [phi:main::@1->main::@3#0] -- pprz1=pprc1 + lda #fn2 + sta.z f+1 + jmp __b3 + // [13] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + // main::@2 + __b2: + // [14] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + // [14] phi main::f#3 = &fn1 [phi:main::@2->main::@3#0] -- pprz1=pprc1 + lda #fn1 + sta.z f+1 + // main::@3 + __b3: + // char v = (*f)() + // sideeffect stackpushbytes(1) -- _stackpushbyte_1 + pha + // [16] callexecute *main::f#3 + jsr bi_f + // [17] main::v#0 = stackpull(byte) -- vbuaa=_stackpullbyte_ + pla + // SCREEN[0] = v + // [18] *main::SCREEN = main::v#0 -- _deref_pbuc1=vbuaa + sta SCREEN + // [9] phi from main::@3 to main::@1 [phi:main::@3->main::@1] + // [9] phi main::i#2 = main::i#1 [phi:main::@3->main::@1#0] -- register_copy + jmp __b1 + bi_f: + jmp (f) +} + // File Data + diff --git a/src/test/ref/function-pointer-return-1.sym b/src/test/ref/function-pointer-return-1.sym new file mode 100644 index 000000000..101fff55e --- /dev/null +++ b/src/test/ref/function-pointer-return-1.sym @@ -0,0 +1,28 @@ +constant word STACK_BASE = $103 +__stackcall byte fn1() +constant byte* const fn1::BORDER_COLOR = (byte*) 53280 +constant byte fn1::OFFSET_STACK_RETURN_0 = 0 +byte fn1::return +byte fn1::return#0 reg byte a 4.0 +__stackcall byte fn2() +constant byte* const fn2::BG_COLOR = (byte*) 53281 +constant byte fn2::OFFSET_STACK_RETURN_0 = 0 +byte fn2::return +byte fn2::return#0 reg byte a 4.0 +void main() +byte~ main::$0 reg byte a 22.0 +constant byte* const main::SCREEN = (byte*) 1024 +byte()* main::f +byte()* main::f#3 f zp[2]:3 +byte main::i +byte main::i#1 i zp[1]:2 8.25 +byte main::i#2 i zp[1]:2 22.0 +byte main::v +byte main::v#0 reg byte a 22.0 + +zp[1]:2 [ main::i#2 main::i#1 ] +zp[2]:3 [ main::f#3 ] +reg byte a [ fn2::return#0 ] +reg byte a [ fn1::return#0 ] +reg byte a [ main::$0 ] +reg byte a [ main::v#0 ] diff --git a/src/test/ref/function-pointer-return.asm b/src/test/ref/function-pointer-return.asm index 110d0ff26..b5f877fce 100644 --- a/src/test/ref/function-pointer-return.asm +++ b/src/test/ref/function-pointer-return.asm @@ -7,19 +7,30 @@ .segmentdef Data [startAfter="Code"] .segment Basic :BasicUpstart(main) + .const STACK_BASE = $103 .segment Code fn2: { + .const OFFSET_STACK_RETURN_0 = 0 .label BG_COLOR = $d021 // (*BG_COLOR)++; inc BG_COLOR + // return *BG_COLOR; + lda BG_COLOR // } + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x rts } fn1: { + .const OFFSET_STACK_RETURN_0 = 0 .label BORDER_COLOR = $d020 // (*BORDER_COLOR)++; inc BORDER_COLOR + // return *BORDER_COLOR; + lda BORDER_COLOR // } + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x rts } main: { diff --git a/src/test/ref/function-pointer-return.cfg b/src/test/ref/function-pointer-return.cfg index f4581bc95..8ceb05fb7 100644 --- a/src/test/ref/function-pointer-return.cfg +++ b/src/test/ref/function-pointer-return.cfg @@ -1,36 +1,40 @@ -byte fn2() +__stackcall byte fn2() fn2: scope:[fn2] from [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR + [1] fn2::return#0 = *fn2::BG_COLOR to:fn2::@return fn2::@return: scope:[fn2] from fn2 - [1] return + [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 + [3] return to:@return -byte fn1() +__stackcall byte fn1() fn1: scope:[fn1] from - [2] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + [5] fn1::return#0 = *fn1::BORDER_COLOR to:fn1::@return fn1::@return: scope:[fn1] from fn1 - [3] return + [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 + [7] return to:@return void main() main: scope:[main] from - [4] phi() + [8] phi() to:main::@1 main::@1: scope:[main] from main main::@4 - [5] main::i#2 = phi( main/0, main::@4/main::i#1 ) + [9] main::i#2 = phi( main/0, main::@4/main::i#1 ) to:main::@2 main::@2: scope:[main] from main::@1 - [6] main::i#1 = ++ main::i#2 - [7] main::$0 = main::i#1 & 1 - [8] if(main::$0==0) goto main::@3 + [10] main::i#1 = ++ main::i#2 + [11] main::$0 = main::i#1 & 1 + [12] if(main::$0==0) goto main::@3 to:main::@4 main::@3: scope:[main] from main::@2 - [9] phi() + [13] phi() to:main::@4 main::@4: scope:[main] from main::@2 main::@3 - [10] main::f#3 = phi( main::@3/&fn1, main::@2/&fn2 ) - [11] *main::SCREEN = (byte)main::f#3 + [14] main::f#3 = phi( main::@3/&fn1, main::@2/&fn2 ) + [15] *main::SCREEN = (byte)main::f#3 to:main::@1 diff --git a/src/test/ref/function-pointer-return.log b/src/test/ref/function-pointer-return.log index 6a79ac052..f0488d832 100644 --- a/src/test/ref/function-pointer-return.log +++ b/src/test/ref/function-pointer-return.log @@ -1,5 +1,9 @@ Resolved forward reference fn1 to byte fn1() Resolved forward reference fn2 to byte fn2() +Setting inferred __stackcall on procedure affected by address-of __stackcall byte fn1() caused by statement main::f = &fn1 +Setting inferred __stackcall on procedure affected by address-of __stackcall byte fn2() caused by statement main::f = &fn2 +Calling convention STACK_CALL adding stack return stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return +Calling convention STACK_CALL adding stack return stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return CONTROL FLOW GRAPH SSA @@ -36,7 +40,7 @@ main::@return: scope:[main] from main::@1 return to:@return -byte fn1() +__stackcall byte fn1() fn1: scope:[fn1] from *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR fn1::return#0 = *fn1::BORDER_COLOR @@ -44,10 +48,11 @@ fn1: scope:[fn1] from fn1::@return: scope:[fn1] from fn1 fn1::return#2 = phi( fn1/fn1::return#0 ) fn1::return#1 = fn1::return#2 + stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#1 return to:@return -byte fn2() +__stackcall byte fn2() fn2: scope:[fn2] from *fn2::BG_COLOR = ++ *fn2::BG_COLOR fn2::return#0 = *fn2::BG_COLOR @@ -55,6 +60,7 @@ fn2: scope:[fn2] from fn2::@return: scope:[fn2] from fn2 fn2::return#2 = phi( fn2/fn2::return#0 ) fn2::return#1 = fn2::return#2 + stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#1 return to:@return @@ -69,15 +75,18 @@ __start::@return: scope:[__start] from __start::@1 to:@return SYMBOL TABLE SSA +constant word STACK_BASE = $103 void __start() -byte fn1() +__stackcall byte fn1() constant byte* const fn1::BORDER_COLOR = (byte*)$d020 +constant byte fn1::OFFSET_STACK_RETURN_0 = 0 byte fn1::return byte fn1::return#0 byte fn1::return#1 byte fn1::return#2 -byte fn2() +__stackcall byte fn2() constant byte* const fn2::BG_COLOR = (byte*)$d021 +constant byte fn2::OFFSET_STACK_RETURN_0 = 0 byte fn2::return byte fn2::return#0 byte fn2::return#1 @@ -137,8 +146,6 @@ Simplifying expression containing zero main::SCREEN in [11] main::SCREEN[0] = (b Successful SSA optimization PassNSimplifyExpressionWithZero Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks -Eliminating unused variable fn1::return#0 and assignment [7] fn1::return#0 = *fn1::BORDER_COLOR -Eliminating unused variable fn2::return#0 and assignment [10] fn2::return#0 = *fn2::BG_COLOR Eliminating unused constant main::f#0 Successful SSA optimization PassNEliminateUnusedVars Removing unused procedure __start @@ -159,7 +166,7 @@ Adding NOP phi() at start of main::@3 CALL GRAPH Created 2 initial phi equivalence classes -Coalesced [12] main::i#7 = main::i#1 +Coalesced [16] main::i#7 = main::i#1 Coalesced down to 2 phi equivalence classes Culled Empty Block label main::@5 Adding NOP phi() at start of main @@ -167,48 +174,54 @@ Adding NOP phi() at start of main::@3 FINAL CONTROL FLOW GRAPH -byte fn2() +__stackcall byte fn2() fn2: scope:[fn2] from [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR + [1] fn2::return#0 = *fn2::BG_COLOR to:fn2::@return fn2::@return: scope:[fn2] from fn2 - [1] return + [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 + [3] return to:@return -byte fn1() +__stackcall byte fn1() fn1: scope:[fn1] from - [2] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR + [5] fn1::return#0 = *fn1::BORDER_COLOR to:fn1::@return fn1::@return: scope:[fn1] from fn1 - [3] return + [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 + [7] return to:@return void main() main: scope:[main] from - [4] phi() + [8] phi() to:main::@1 main::@1: scope:[main] from main main::@4 - [5] main::i#2 = phi( main/0, main::@4/main::i#1 ) + [9] main::i#2 = phi( main/0, main::@4/main::i#1 ) to:main::@2 main::@2: scope:[main] from main::@1 - [6] main::i#1 = ++ main::i#2 - [7] main::$0 = main::i#1 & 1 - [8] if(main::$0==0) goto main::@3 + [10] main::i#1 = ++ main::i#2 + [11] main::$0 = main::i#1 & 1 + [12] if(main::$0==0) goto main::@3 to:main::@4 main::@3: scope:[main] from main::@2 - [9] phi() + [13] phi() to:main::@4 main::@4: scope:[main] from main::@2 main::@3 - [10] main::f#3 = phi( main::@3/&fn1, main::@2/&fn2 ) - [11] *main::SCREEN = (byte)main::f#3 + [14] main::f#3 = phi( main::@3/&fn1, main::@2/&fn2 ) + [15] *main::SCREEN = (byte)main::f#3 to:main::@1 VARIABLE REGISTER WEIGHTS -byte fn1() +__stackcall byte fn1() byte fn1::return -byte fn2() +byte fn1::return#0 4.0 +__stackcall byte fn2() byte fn2::return +byte fn2::return#0 4.0 void main() byte~ main::$0 22.0 byte()* main::f @@ -220,33 +233,45 @@ byte main::i#2 22.0 Initial phi equivalence classes [ main::i#2 main::i#1 ] [ main::f#3 ] +Added variable fn2::return#0 to live range equivalence class [ fn2::return#0 ] +Added variable fn1::return#0 to live range equivalence class [ fn1::return#0 ] Added variable main::$0 to live range equivalence class [ main::$0 ] Complete equivalence classes [ main::i#2 main::i#1 ] [ main::f#3 ] +[ fn2::return#0 ] +[ fn1::return#0 ] [ main::$0 ] Allocated zp[1]:2 [ main::i#2 main::i#1 ] Allocated zp[2]:3 [ main::f#3 ] -Allocated zp[1]:5 [ main::$0 ] +Allocated zp[1]:5 [ fn2::return#0 ] +Allocated zp[1]:6 [ fn1::return#0 ] +Allocated zp[1]:7 [ main::$0 ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [11] *main::SCREEN = (byte)main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a +Statement [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [15] *main::SCREEN = (byte)main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [7] main::$0 = main::i#1 & 1 [ main::i#1 main::$0 ] ( [ main::i#1 main::$0 ] { } ) always clobbers reg byte a -Statement [11] *main::SCREEN = (byte)main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a +Statement [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 [ ] ( [ ] { } ) always clobbers reg byte x +Statement [11] main::$0 = main::i#1 & 1 [ main::i#1 main::$0 ] ( [ main::i#1 main::$0 ] { } ) always clobbers reg byte a +Statement [15] *main::SCREEN = (byte)main::f#3 [ main::i#1 ] ( [ main::i#1 ] { } ) always clobbers reg byte a Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y , Potential registers zp[2]:3 [ main::f#3 ] : zp[2]:3 , -Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:5 [ fn2::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:6 [ fn1::return#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:7 [ main::$0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 27.5: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:5 [ main::$0 ] 0: zp[2]:3 [ main::f#3 ] -Uplift Scope [fn1] -Uplift Scope [fn2] +Uplift Scope [main] 27.5: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:7 [ main::$0 ] 0: zp[2]:3 [ main::f#3 ] +Uplift Scope [fn1] 4: zp[1]:6 [ fn1::return#0 ] +Uplift Scope [fn2] 4: zp[1]:5 [ fn2::return#0 ] Uplift Scope [] -Uplifting [main] best 605 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] zp[2]:3 [ main::f#3 ] -Uplifting [fn1] best 605 combination -Uplifting [fn2] best 605 combination -Uplifting [] best 605 combination +Uplifting [main] best 639 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] zp[2]:3 [ main::f#3 ] +Uplifting [fn1] best 633 combination reg byte a [ fn1::return#0 ] +Uplifting [fn2] best 627 combination reg byte a [ fn2::return#0 ] +Uplifting [] best 627 combination Allocated (was zp[2]:3) zp[2]:2 [ main::f#3 ] ASSEMBLER BEFORE OPTIMIZATION @@ -262,36 +287,49 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Basic :BasicUpstart(main) // Global Constants & labels + .const STACK_BASE = $103 .segment Code // fn2 fn2: { + .const OFFSET_STACK_RETURN_0 = 0 .label BG_COLOR = $d021 // [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 inc BG_COLOR + // [1] fn2::return#0 = *fn2::BG_COLOR -- vbuaa=_deref_pbuc1 + lda BG_COLOR jmp __breturn // fn2::@return __breturn: - // [1] return + // [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [3] return rts } // fn1 fn1: { + .const OFFSET_STACK_RETURN_0 = 0 .label BORDER_COLOR = $d020 - // [2] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 + // [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 inc BORDER_COLOR + // [5] fn1::return#0 = *fn1::BORDER_COLOR -- vbuaa=_deref_pbuc1 + lda BORDER_COLOR jmp __breturn // fn1::@return __breturn: - // [3] return + // [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [7] return rts } // main main: { .label SCREEN = $400 .label f = 2 - // [5] phi from main to main::@1 [phi:main->main::@1] + // [9] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [5] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + // [9] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 ldx #0 jmp __b1 // main::@1 @@ -299,30 +337,30 @@ main: { jmp __b2 // main::@2 __b2: - // [6] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx + // [10] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx inx - // [7] main::$0 = main::i#1 & 1 -- vbuaa=vbuxx_band_vbuc1 + // [11] main::$0 = main::i#1 & 1 -- vbuaa=vbuxx_band_vbuc1 txa and #1 - // [8] if(main::$0==0) goto main::@3 -- vbuaa_eq_0_then_la1 + // [12] if(main::$0==0) goto main::@3 -- vbuaa_eq_0_then_la1 cmp #0 beq __b3_from___b2 - // [10] phi from main::@2 to main::@4 [phi:main::@2->main::@4] + // [14] phi from main::@2 to main::@4 [phi:main::@2->main::@4] __b4_from___b2: - // [10] phi main::f#3 = &fn2 [phi:main::@2->main::@4#0] -- pprz1=pprc1 + // [14] phi main::f#3 = &fn2 [phi:main::@2->main::@4#0] -- pprz1=pprc1 lda #fn2 sta.z f+1 jmp __b4 - // [9] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + // [13] phi from main::@2 to main::@3 [phi:main::@2->main::@3] __b3_from___b2: jmp __b3 // main::@3 __b3: - // [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + // [14] phi from main::@3 to main::@4 [phi:main::@3->main::@4] __b4_from___b3: - // [10] phi main::f#3 = &fn1 [phi:main::@3->main::@4#0] -- pprz1=pprc1 + // [14] phi main::f#3 = &fn1 [phi:main::@3->main::@4#0] -- pprz1=pprc1 lda #fn1 @@ -330,12 +368,12 @@ main: { jmp __b4 // main::@4 __b4: - // [11] *main::SCREEN = (byte)main::f#3 -- _deref_pbuc1=_byte_pprz1 + // [15] *main::SCREEN = (byte)main::f#3 -- _deref_pbuc1=_byte_pprz1 lda.z f sta SCREEN - // [5] phi from main::@4 to main::@1 [phi:main::@4->main::@1] + // [9] phi from main::@4 to main::@1 [phi:main::@4->main::@1] __b1_from___b4: - // [5] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy + // [9] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy jmp __b1 } // File Data @@ -362,12 +400,17 @@ Removing instruction __b1_from___b4: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE -byte fn1() +constant word STACK_BASE = $103 +__stackcall byte fn1() constant byte* const fn1::BORDER_COLOR = (byte*) 53280 +constant byte fn1::OFFSET_STACK_RETURN_0 = 0 byte fn1::return -byte fn2() +byte fn1::return#0 reg byte a 4.0 +__stackcall byte fn2() constant byte* const fn2::BG_COLOR = (byte*) 53281 +constant byte fn2::OFFSET_STACK_RETURN_0 = 0 byte fn2::return +byte fn2::return#0 reg byte a 4.0 void main() byte~ main::$0 reg byte a 22.0 constant byte* const main::SCREEN = (byte*) 1024 @@ -379,11 +422,13 @@ byte main::i#2 reg byte x 22.0 reg byte x [ main::i#2 main::i#1 ] zp[2]:2 [ main::f#3 ] +reg byte a [ fn2::return#0 ] +reg byte a [ fn1::return#0 ] reg byte a [ main::$0 ] FINAL ASSEMBLER -Score: 479 +Score: 501 // File Comments // Tests creating and assigning pointers to non-args return with function value @@ -397,62 +442,77 @@ Score: 479 .segment Basic :BasicUpstart(main) // Global Constants & labels + .const STACK_BASE = $103 .segment Code // fn2 fn2: { + .const OFFSET_STACK_RETURN_0 = 0 .label BG_COLOR = $d021 // (*BG_COLOR)++; // [0] *fn2::BG_COLOR = ++ *fn2::BG_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 inc BG_COLOR + // return *BG_COLOR; + // [1] fn2::return#0 = *fn2::BG_COLOR -- vbuaa=_deref_pbuc1 + lda BG_COLOR // fn2::@return // } - // [1] return + // [2] stackidx(byte,fn2::OFFSET_STACK_RETURN_0) = fn2::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [3] return rts } // fn1 fn1: { + .const OFFSET_STACK_RETURN_0 = 0 .label BORDER_COLOR = $d020 // (*BORDER_COLOR)++; - // [2] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 + // [4] *fn1::BORDER_COLOR = ++ *fn1::BORDER_COLOR -- _deref_pbuc1=_inc__deref_pbuc1 inc BORDER_COLOR + // return *BORDER_COLOR; + // [5] fn1::return#0 = *fn1::BORDER_COLOR -- vbuaa=_deref_pbuc1 + lda BORDER_COLOR // fn1::@return // } - // [3] return + // [6] stackidx(byte,fn1::OFFSET_STACK_RETURN_0) = fn1::return#0 -- _stackidxbyte_vbuc1=vbuaa + tsx + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + // [7] return rts } // main main: { .label SCREEN = $400 .label f = 2 - // [5] phi from main to main::@1 [phi:main->main::@1] - // [5] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + // [9] phi from main to main::@1 [phi:main->main::@1] + // [9] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 ldx #0 // main::@1 // main::@2 __b2: // ++i; - // [6] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx + // [10] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx inx // i&1 - // [7] main::$0 = main::i#1 & 1 -- vbuaa=vbuxx_band_vbuc1 + // [11] main::$0 = main::i#1 & 1 -- vbuaa=vbuxx_band_vbuc1 txa and #1 // if((i&1)==0) - // [8] if(main::$0==0) goto main::@3 -- vbuaa_eq_0_then_la1 + // [12] if(main::$0==0) goto main::@3 -- vbuaa_eq_0_then_la1 cmp #0 beq __b3 - // [10] phi from main::@2 to main::@4 [phi:main::@2->main::@4] - // [10] phi main::f#3 = &fn2 [phi:main::@2->main::@4#0] -- pprz1=pprc1 + // [14] phi from main::@2 to main::@4 [phi:main::@2->main::@4] + // [14] phi main::f#3 = &fn2 [phi:main::@2->main::@4#0] -- pprz1=pprc1 lda #fn2 sta.z f+1 jmp __b4 - // [9] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + // [13] phi from main::@2 to main::@3 [phi:main::@2->main::@3] // main::@3 __b3: - // [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] - // [10] phi main::f#3 = &fn1 [phi:main::@3->main::@4#0] -- pprz1=pprc1 + // [14] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + // [14] phi main::f#3 = &fn1 [phi:main::@3->main::@4#0] -- pprz1=pprc1 lda #fn1 @@ -460,11 +520,11 @@ main: { // main::@4 __b4: // SCREEN[0] = (byte)f - // [11] *main::SCREEN = (byte)main::f#3 -- _deref_pbuc1=_byte_pprz1 + // [15] *main::SCREEN = (byte)main::f#3 -- _deref_pbuc1=_byte_pprz1 lda.z f sta SCREEN - // [5] phi from main::@4 to main::@1 [phi:main::@4->main::@1] - // [5] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy + // [9] phi from main::@4 to main::@1 [phi:main::@4->main::@1] + // [9] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy jmp __b2 } // File Data diff --git a/src/test/ref/function-pointer-return.sym b/src/test/ref/function-pointer-return.sym index 2f8ea871b..8afbf2623 100644 --- a/src/test/ref/function-pointer-return.sym +++ b/src/test/ref/function-pointer-return.sym @@ -1,9 +1,14 @@ -byte fn1() +constant word STACK_BASE = $103 +__stackcall byte fn1() constant byte* const fn1::BORDER_COLOR = (byte*) 53280 +constant byte fn1::OFFSET_STACK_RETURN_0 = 0 byte fn1::return -byte fn2() +byte fn1::return#0 reg byte a 4.0 +__stackcall byte fn2() constant byte* const fn2::BG_COLOR = (byte*) 53281 +constant byte fn2::OFFSET_STACK_RETURN_0 = 0 byte fn2::return +byte fn2::return#0 reg byte a 4.0 void main() byte~ main::$0 reg byte a 22.0 constant byte* const main::SCREEN = (byte*) 1024 @@ -15,4 +20,6 @@ byte main::i#2 reg byte x 22.0 reg byte x [ main::i#2 main::i#1 ] zp[2]:2 [ main::f#3 ] +reg byte a [ fn2::return#0 ] +reg byte a [ fn1::return#0 ] reg byte a [ main::$0 ] diff --git a/src/test/ref/procedure-callingconvention-stack-0.asm b/src/test/ref/procedure-callingconvention-stack-0.asm index c1be5b20b..eaa78b5e5 100644 --- a/src/test/ref/procedure-callingconvention-stack-0.asm +++ b/src/test/ref/procedure-callingconvention-stack-0.asm @@ -14,7 +14,7 @@ plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 2 tsx lda STACK_BASE+OFFSET_STACK_A,x @@ -26,7 +26,7 @@ plus: { adc.z a // } tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-0.cfg b/src/test/ref/procedure-callingconvention-stack-0.cfg index 99890c7e4..48fad4ba5 100644 --- a/src/test/ref/procedure-callingconvention-stack-0.cfg +++ b/src/test/ref/procedure-callingconvention-stack-0.cfg @@ -6,7 +6,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [4] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-0.log b/src/test/ref/procedure-callingconvention-stack-0.log index e1b2a0044..63cf2e642 100644 --- a/src/test/ref/procedure-callingconvention-stack-0.log +++ b/src/test/ref/procedure-callingconvention-stack-0.log @@ -3,7 +3,7 @@ Adding parameter assignment in __stackcall procedure plus::a = param(plus::a) Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7 Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B) -Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return +Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(byte) Calling convention STACK_CALL adding stack push stackpush(byte) = '0' Calling convention STACK_CALL adding stack push stackpush(byte) = 7 @@ -32,7 +32,7 @@ plus: scope:[plus] from to:plus::@return plus::@return: scope:[plus] from plus plus::return#1 = phi( plus/plus::return#0 ) - stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#1 + stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#1 return to:@return @@ -56,7 +56,7 @@ __stackcall byte plus(byte plus::a , byte plus::b) byte~ plus::$0 constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 byte plus::b @@ -103,7 +103,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [4] return to:@return @@ -152,7 +152,7 @@ Statement [1] plus::b#0 = stackidx(byte,plus::OFFSET_STACK_B) [ plus::a#0 plus:: Removing always clobbered register reg byte a as potential for zp[1]:2 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:2 [ plus::a#0 ] Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a -Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x +Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x Statement [5] stackpush(byte) = '0' [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] stackpush(byte) = 7 [ ] ( [ ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(1) always clobbers reg byte a @@ -160,7 +160,7 @@ Statement [9] main::$0 = stackpull(byte) [ main::$0 ] ( [ main::$0 ] { } ) alw Statement [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x Statement [1] plus::b#0 = stackidx(byte,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a -Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x +Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x Statement [5] stackpush(byte) = '0' [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] stackpush(byte) = 7 [ ] ( [ ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(1) always clobbers reg byte a @@ -202,7 +202,7 @@ ASSEMBLER BEFORE OPTIMIZATION plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 2 // [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -217,9 +217,9 @@ plus: { jmp __breturn // plus::@return __breturn: - // [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [4] return rts } @@ -263,7 +263,7 @@ byte~ main::$0 reg byte a 4.0 __stackcall byte plus(byte plus::a , byte plus::b) constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 a zp[1]:2 11.0 byte plus::b @@ -300,7 +300,7 @@ Score: 67 plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 2 // [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -315,9 +315,9 @@ plus: { adc.z a // plus::@return // } - // [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [4] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-0.sym b/src/test/ref/procedure-callingconvention-stack-0.sym index 81e7bc8a2..5f814603d 100644 --- a/src/test/ref/procedure-callingconvention-stack-0.sym +++ b/src/test/ref/procedure-callingconvention-stack-0.sym @@ -5,7 +5,7 @@ byte~ main::$0 reg byte a 4.0 __stackcall byte plus(byte plus::a , byte plus::b) constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 a zp[1]:2 11.0 byte plus::b diff --git a/src/test/ref/procedure-callingconvention-stack-1.asm b/src/test/ref/procedure-callingconvention-stack-1.asm index fc730c904..918d5d445 100644 --- a/src/test/ref/procedure-callingconvention-stack-1.asm +++ b/src/test/ref/procedure-callingconvention-stack-1.asm @@ -14,7 +14,7 @@ plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 2 tsx lda STACK_BASE+OFFSET_STACK_A,x @@ -26,7 +26,7 @@ plus: { adc.z a // } tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-1.cfg b/src/test/ref/procedure-callingconvention-stack-1.cfg index 99890c7e4..48fad4ba5 100644 --- a/src/test/ref/procedure-callingconvention-stack-1.cfg +++ b/src/test/ref/procedure-callingconvention-stack-1.cfg @@ -6,7 +6,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [4] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-1.log b/src/test/ref/procedure-callingconvention-stack-1.log index cc61ae2b7..0ae183101 100644 --- a/src/test/ref/procedure-callingconvention-stack-1.log +++ b/src/test/ref/procedure-callingconvention-stack-1.log @@ -3,7 +3,7 @@ Adding parameter assignment in __stackcall procedure plus::a = param(plus::a) Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7 Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B) -Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return +Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(byte) Calling convention STACK_CALL adding stack push stackpush(byte) = '0' Calling convention STACK_CALL adding stack push stackpush(byte) = 7 @@ -32,7 +32,7 @@ plus: scope:[plus] from to:plus::@return plus::@return: scope:[plus] from plus plus::return#1 = phi( plus/plus::return#0 ) - stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#1 + stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#1 return to:@return @@ -56,7 +56,7 @@ __stackcall byte plus(byte plus::a , byte plus::b) byte~ plus::$0 constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 byte plus::b @@ -103,7 +103,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [4] return to:@return @@ -152,7 +152,7 @@ Statement [1] plus::b#0 = stackidx(byte,plus::OFFSET_STACK_B) [ plus::a#0 plus:: Removing always clobbered register reg byte a as potential for zp[1]:2 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:2 [ plus::a#0 ] Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a -Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x +Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x Statement [5] stackpush(byte) = '0' [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] stackpush(byte) = 7 [ ] ( [ ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(1) always clobbers reg byte a @@ -160,7 +160,7 @@ Statement [9] main::$0 = stackpull(byte) [ main::$0 ] ( [ main::$0 ] { } ) alw Statement [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x Statement [1] plus::b#0 = stackidx(byte,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a -Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x +Statement [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x Statement [5] stackpush(byte) = '0' [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] stackpush(byte) = 7 [ ] ( [ ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(1) always clobbers reg byte a @@ -202,7 +202,7 @@ ASSEMBLER BEFORE OPTIMIZATION plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 2 // [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -217,9 +217,9 @@ plus: { jmp __breturn // plus::@return __breturn: - // [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [4] return rts } @@ -263,7 +263,7 @@ byte~ main::$0 reg byte a 4.0 __stackcall byte plus(byte plus::a , byte plus::b) constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 a zp[1]:2 11.0 byte plus::b @@ -300,7 +300,7 @@ Score: 67 plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 2 // [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -315,9 +315,9 @@ plus: { adc.z a // plus::@return // } - // [3] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [3] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [4] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-1.sym b/src/test/ref/procedure-callingconvention-stack-1.sym index 81e7bc8a2..5f814603d 100644 --- a/src/test/ref/procedure-callingconvention-stack-1.sym +++ b/src/test/ref/procedure-callingconvention-stack-1.sym @@ -5,7 +5,7 @@ byte~ main::$0 reg byte a 4.0 __stackcall byte plus(byte plus::a , byte plus::b) constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 a zp[1]:2 11.0 byte plus::b diff --git a/src/test/ref/procedure-callingconvention-stack-10.asm b/src/test/ref/procedure-callingconvention-stack-10.asm index dbaca4268..fbb07673c 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.asm +++ b/src/test/ref/procedure-callingconvention-stack-10.asm @@ -8,8 +8,9 @@ .segmentdef Data [startAfter="Code"] .segment Basic :BasicUpstart(__start) - .const STACK_BASE = $103 .const OFFSET_STRUCT_POINT_Y = 1 + .const SIZEOF_STRUCT_POINT = 2 + .const STACK_BASE = $103 .label SCREEN = $400 .label idx = 3 .segment Code @@ -20,50 +21,62 @@ __start: { jsr main rts } -// print(byte register(Y) p_x, byte register(X) p_y) +// print(struct Point zp(4) p) print: { - .const OFFSET_STACK_P_X = 1 - .const OFFSET_STACK_P_Y = 0 + .const OFFSET_STACK_P = 0 + .label p = 4 tsx - lda STACK_BASE+OFFSET_STACK_P_X,x - tay - tsx - lda STACK_BASE+OFFSET_STACK_P_Y,x - tax + lda STACK_BASE+OFFSET_STACK_P,x + sta.z p + lda STACK_BASE+OFFSET_STACK_P+1,x + sta.z p+1 // SCREEN[idx++] = p.x - tya + lda.z p ldy.z idx sta SCREEN,y // SCREEN[idx++] = p.x; inc.z idx // SCREEN[idx++] = p.y + lda p+OFFSET_STRUCT_POINT_Y ldy.z idx - txa sta SCREEN,y // SCREEN[idx++] = p.y; inc.z idx // } rts } +// get(byte register(X) i) get: { .const OFFSET_STACK_I = 0 + .const OFFSET_STACK_RETURN_0 = 0 + .label return = 6 + .label p = 8 tsx lda STACK_BASE+OFFSET_STACK_I,x tax // i/2 txa lsr - tay + // struct Point p = { i, i/2 } + stx.z p + sta p+OFFSET_STRUCT_POINT_Y + // return p; + ldy #SIZEOF_STRUCT_POINT + !: + lda p-1,y + sta return-1,y + dey + bne !- // } - txa tsx - sta STACK_BASE+0,x - tya - tsx - sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x + lda.z return + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + lda.z return+1 + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x rts } main: { + .label p = 4 .label i = 2 lda #0 sta.z i @@ -81,13 +94,12 @@ main: { pha jsr get pla - tay + sta.z p pla - tax + sta.z p+1 // print(p) - tya pha - txa + lda.z p pha jsr print pla diff --git a/src/test/ref/procedure-callingconvention-stack-10.cfg b/src/test/ref/procedure-callingconvention-stack-10.cfg index 4f3414bbd..1b10a8760 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.cfg +++ b/src/test/ref/procedure-callingconvention-stack-10.cfg @@ -14,50 +14,49 @@ __start::@return: scope:[__start] from __start::@1 [4] return to:@return -__stackcall void print(byte print::p_x , byte print::p_y) +__stackcall void print(struct Point print::p) print: scope:[print] from - [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) - [6] print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) - [7] SCREEN[idx] = print::p_x#0 - [8] idx = ++ idx - [9] SCREEN[idx] = print::p_y#0 - [10] idx = ++ idx + [5] print::p = stackidx(struct Point,print::OFFSET_STACK_P) + [6] SCREEN[idx] = *((byte*)&print::p) + [7] idx = ++ idx + [8] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) + [9] idx = ++ idx to:print::@return print::@return: scope:[print] from print - [11] return + [10] return to:@return __stackcall struct Point get(byte get::i) get: scope:[get] from - [12] get::return_x#0 = stackidx(byte,get::OFFSET_STACK_I) - [13] get::return_y#0 = get::return_x#0 >> 1 + [11] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) + [12] get::$0 = get::i#0 >> 1 + [13] *((byte*)&get::p) = get::i#0 + [14] *((byte*)&get::p+OFFSET_STRUCT_POINT_Y) = get::$0 + [15] *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) to:get::@return get::@return: scope:[get] from get - [14] stackidx(byte,0) = get::return_x#0 - [15] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_y#0 - [16] return + [16] stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return + [17] return to:@return __stackcall void main() main: scope:[main] from - [17] phi() + [18] phi() to:main::@1 main::@1: scope:[main] from main main::@2 - [18] main::i#2 = phi( main/0, main::@2/main::i#1 ) - [19] if(main::i#2<5) goto main::@2 + [19] main::i#2 = phi( main/0, main::@2/main::i#1 ) + [20] if(main::i#2<5) goto main::@2 to:main::@return main::@return: scope:[main] from main::@1 - [20] return + [21] return to:@return main::@2: scope:[main] from main::@1 - [21] stackpush(byte) = main::i#2 + [22] stackpush(byte) = main::i#2 sideeffect stackpushbytes(1) - [23] callexecute get - [24] main::p_x#0 = stackpull(byte) - [25] main::p_y#0 = stackpull(byte) - [26] stackpush(byte) = main::p_x#0 - [27] stackpush(byte) = main::p_y#0 - [28] callexecute print + [24] callexecute get + [25] main::p = stackpull(struct Point) + [26] stackpush(struct Point) = main::p + [27] callexecute print sideeffect stackpullbytes(2) - [30] main::i#1 = ++ main::i#2 + [29] main::i#1 = ++ main::i#2 to:main::@1 diff --git a/src/test/ref/procedure-callingconvention-stack-10.log b/src/test/ref/procedure-callingconvention-stack-10.log index 094a74f82..8b3a1afe0 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.log +++ b/src/test/ref/procedure-callingconvention-stack-10.log @@ -3,19 +3,17 @@ Adding parameter assignment in __stackcall procedure get::i = param(get::i) Adding parameter assignment in __stackcall procedure print::p = param(print::p) Inlined call call __init Eliminating unused variable with no statement main::$1 -Calling convention __stackcall adding prepare/execute/finalize for { main::p_x, main::p_y } = call get main::i -Calling convention __stackcall adding prepare/execute/finalize for call print main::p_x main::p_y +Calling convention __stackcall adding prepare/execute/finalize for main::p = call get main::i +Calling convention __stackcall adding prepare/execute/finalize for call print main::p Calling convention __stackcall adding prepare/execute/finalize for call main Calling convention STACK_CALL replacing param(get::i) with stackidx(byte,get::OFFSET_STACK_I) -Calling convention STACK_CALL replacing param(print::p_x) with stackidx(byte,print::OFFSET_STACK_P_X) -Calling convention STACK_CALL replacing param(print::p_y) with stackidx(byte,print::OFFSET_STACK_P_Y) -Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X) = get::return_x -Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y) = get::return_y -Calling convention STACK_CALL adding stack pull main::p_x = stackpull(byte) -Calling convention STACK_CALL adding stack pull main::p_y = stackpull(byte) +Calling convention STACK_CALL replacing param(print::p) with stackidx(struct Point,print::OFFSET_STACK_P) +Calling convention STACK_CALL adding stack return stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return +Calling convention STACK_CALL adding stack pull main::p = stackpull(struct Point) Calling convention STACK_CALL adding stack push stackpush(byte) = main::i -Calling convention STACK_CALL adding stack push stackpush(byte) = main::p_x -Calling convention STACK_CALL adding stack push stackpush(byte) = main::p_y +Calling convention STACK_CALL adding stack push stackpush(struct Point) = main::p +Removing C-classic struct-unwound assignment get::p = struct-unwound {*((byte*)&get::p+OFFSET_STRUCT_POINT_X), *((byte*)&get::p+OFFSET_STRUCT_POINT_Y)} +Removing C-classic struct-unwound assignment get::return = struct-unwound {*(&get::return)} CONTROL FLOW GRAPH SSA @@ -33,10 +31,8 @@ main::@2: scope:[main] from main::@1 stackpush(byte) = main::i#3 sideeffect stackpushbytes(1) callexecute get - main::p_x#0 = stackpull(byte) - main::p_y#0 = stackpull(byte) - stackpush(byte) = main::p_x#0 - stackpush(byte) = main::p_y#0 + main::p = stackpull(struct Point) + stackpush(struct Point) = main::p callexecute print sideeffect stackpullbytes(2) main::i#1 = ++ main::i#3 @@ -49,27 +45,21 @@ __stackcall struct Point get(byte get::i) get: scope:[get] from get::i#0 = stackidx(byte,get::OFFSET_STACK_I) get::$0 = get::i#0 / 2 - get::p_x#0 = get::i#0 - get::p_y#0 = get::$0 - get::return_x#0 = get::p_x#0 - get::return_y#0 = get::p_y#0 - get::return#0 = struct-unwound {get::return_x#0, get::return_y#0} + *((byte*)&get::p+OFFSET_STRUCT_POINT_X) = get::i#0 + *((byte*)&get::p+OFFSET_STRUCT_POINT_Y) = get::$0 + *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) to:get::@return get::@return: scope:[get] from get - get::return_y#1 = phi( get/get::return_y#0 ) - get::return_x#1 = phi( get/get::return_x#0 ) - stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X) = get::return_x#1 - stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y) = get::return_y#1 + stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return return to:@return -__stackcall void print(byte print::p_x , byte print::p_y) +__stackcall void print(struct Point print::p) print: scope:[print] from - print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) - print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) - SCREEN[idx] = print::p_x#0 + print::p = stackidx(struct Point,print::OFFSET_STACK_P) + SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_X) idx = ++ idx - SCREEN[idx] = print::p_y#0 + SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) idx = ++ idx to:print::@return print::@return: scope:[print] from print @@ -93,26 +83,17 @@ SYMBOL TABLE SSA constant byte OFFSET_STRUCT_POINT_X = 0 constant byte OFFSET_STRUCT_POINT_Y = 1 constant byte* const SCREEN = (byte*)$400 +constant byte SIZEOF_STRUCT_POINT = 2 constant word STACK_BASE = $103 void __start() __stackcall struct Point get(byte get::i) number~ get::$0 constant byte get::OFFSET_STACK_I = 0 -constant byte get::OFFSET_STACK_RETURN = 0 +constant byte get::OFFSET_STACK_RETURN_0 = 0 byte get::i byte get::i#0 -byte get::p_x -byte get::p_x#0 -byte get::p_y -byte get::p_y#0 -struct Point get::return -struct Point get::return#0 -byte get::return_x -byte get::return_x#0 -byte get::return_x#1 -byte get::return_y -byte get::return_y#0 -byte get::return_y#1 +struct Point get::p loadstore +struct Point get::return loadstore byte idx loadstore __stackcall void main() bool~ main::$0 @@ -121,18 +102,10 @@ byte main::i#0 byte main::i#1 byte main::i#2 byte main::i#3 -struct Point main::p -byte main::p_x -byte main::p_x#0 -byte main::p_y -byte main::p_y#0 -__stackcall void print(byte print::p_x , byte print::p_y) -constant byte print::OFFSET_STACK_P_X = 1 -constant byte print::OFFSET_STACK_P_Y = 0 -byte print::p_x -byte print::p_x#0 -byte print::p_y -byte print::p_y#0 +struct Point main::p loadstore +__stackcall void print(struct Point print::p) +constant byte print::OFFSET_STACK_P = 0 +struct Point print::p loadstore Adding number conversion cast (unumber) 5 in main::$0 = main::i#2 < 5 Adding number conversion cast (unumber) 2 in get::$0 = get::i#0 / 2 @@ -147,22 +120,17 @@ Finalized unsigned number type (byte) 2 Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to byte in get::$0 = get::i#0 / 2 Alias main::i#2 = main::i#3 -Alias get::return_x#0 = get::p_x#0 get::i#0 get::return_x#1 -Alias get::return_y#0 = get::p_y#0 get::$0 get::return_y#1 Successful SSA optimization Pass2AliasElimination Simple Condition main::$0 [3] if(main::i#2<5) goto main::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Constant main::i#0 = 0 Successful SSA optimization Pass2ConstantIdentification -Simplifying constant evaluating to zero get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X in [18] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X) = get::return_x#0 -Successful SSA optimization PassNSimplifyConstantZero -Simplifying expression containing zero OFFSET_STRUCT_POINT_Y in [19] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y) = get::return_y#0 +Simplifying expression containing zero (byte*)&get::p in [15] *((byte*)&get::p+OFFSET_STRUCT_POINT_X) = get::i#0 +Simplifying expression containing zero (byte*)&print::p in [21] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_X) Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable get::return#0 and assignment [15] get::return#0 = struct-unwound {get::return_x#0, get::return_y#0} -Eliminating unused constant get::OFFSET_STACK_RETURN Eliminating unused constant OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars -Rewriting division to use shift [14] get::return_y#0 = get::return_x#0 / 2 +Rewriting division to use shift [12] get::$0 = get::i#0 / 2 Successful SSA optimization Pass2MultiplyToShiftRewriting Inlining constant with var siblings main::i#0 Constant inlined main::i#0 = 0 @@ -175,10 +143,10 @@ Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of main CALL GRAPH Calls in [__start] to main:3 -Calls in [main] to get:23 print:28 +Calls in [main] to get:24 print:27 Created 1 initial phi equivalence classes -Coalesced [31] main::i#4 = main::i#1 +Coalesced [30] main::i#4 = main::i#1 Coalesced down to 1 phi equivalence classes Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 @@ -201,52 +169,51 @@ __start::@return: scope:[__start] from __start::@1 [4] return to:@return -__stackcall void print(byte print::p_x , byte print::p_y) +__stackcall void print(struct Point print::p) print: scope:[print] from - [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) - [6] print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) - [7] SCREEN[idx] = print::p_x#0 - [8] idx = ++ idx - [9] SCREEN[idx] = print::p_y#0 - [10] idx = ++ idx + [5] print::p = stackidx(struct Point,print::OFFSET_STACK_P) + [6] SCREEN[idx] = *((byte*)&print::p) + [7] idx = ++ idx + [8] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) + [9] idx = ++ idx to:print::@return print::@return: scope:[print] from print - [11] return + [10] return to:@return __stackcall struct Point get(byte get::i) get: scope:[get] from - [12] get::return_x#0 = stackidx(byte,get::OFFSET_STACK_I) - [13] get::return_y#0 = get::return_x#0 >> 1 + [11] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) + [12] get::$0 = get::i#0 >> 1 + [13] *((byte*)&get::p) = get::i#0 + [14] *((byte*)&get::p+OFFSET_STRUCT_POINT_Y) = get::$0 + [15] *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) to:get::@return get::@return: scope:[get] from get - [14] stackidx(byte,0) = get::return_x#0 - [15] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_y#0 - [16] return + [16] stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return + [17] return to:@return __stackcall void main() main: scope:[main] from - [17] phi() + [18] phi() to:main::@1 main::@1: scope:[main] from main main::@2 - [18] main::i#2 = phi( main/0, main::@2/main::i#1 ) - [19] if(main::i#2<5) goto main::@2 + [19] main::i#2 = phi( main/0, main::@2/main::i#1 ) + [20] if(main::i#2<5) goto main::@2 to:main::@return main::@return: scope:[main] from main::@1 - [20] return + [21] return to:@return main::@2: scope:[main] from main::@1 - [21] stackpush(byte) = main::i#2 + [22] stackpush(byte) = main::i#2 sideeffect stackpushbytes(1) - [23] callexecute get - [24] main::p_x#0 = stackpull(byte) - [25] main::p_y#0 = stackpull(byte) - [26] stackpush(byte) = main::p_x#0 - [27] stackpush(byte) = main::p_y#0 - [28] callexecute print + [24] callexecute get + [25] main::p = stackpull(struct Point) + [26] stackpush(struct Point) = main::p + [27] callexecute print sideeffect stackpullbytes(2) - [30] main::i#1 = ++ main::i#2 + [29] main::i#1 = ++ main::i#2 to:main::@1 null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 main::@1 in scope print @@ -255,128 +222,108 @@ null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 VARIABLE REGISTER WEIGHTS void __start() __stackcall struct Point get(byte get::i) +byte~ get::$0 1001.0 byte get::i -byte get::p_x -byte get::p_y -struct Point get::return -byte get::return_x -byte get::return_x#0 1501.5 -byte get::return_y -byte get::return_y#0 1001.0 -byte idx loadstore 273.0909090909091 +byte get::i#0 1501.5 +struct Point get::p loadstore +struct Point get::return loadstore 47.666666666666664 +byte idx loadstore 316.2105263157895 __stackcall void main() byte main::i byte main::i#1 202.0 -byte main::i#2 36.72727272727273 -struct Point main::p -byte main::p_x -byte main::p_x#0 101.0 -byte main::p_y -byte main::p_y#0 101.0 -__stackcall void print(byte print::p_x , byte print::p_y) -byte print::p_x -byte print::p_x#0 1001.0 -byte print::p_y -byte print::p_y#0 667.3333333333334 +byte main::i#2 44.888888888888886 +struct Point main::p loadstore 202.0 +__stackcall void print(struct Point print::p) +struct Point print::p loadstore 333.6666666666667 Initial phi equivalence classes [ main::i#2 main::i#1 ] Added variable idx to live range equivalence class [ idx ] -Added variable print::p_x#0 to live range equivalence class [ print::p_x#0 ] -Added variable print::p_y#0 to live range equivalence class [ print::p_y#0 ] -Added variable get::return_x#0 to live range equivalence class [ get::return_x#0 ] -Added variable get::return_y#0 to live range equivalence class [ get::return_y#0 ] -Added variable main::p_x#0 to live range equivalence class [ main::p_x#0 ] -Added variable main::p_y#0 to live range equivalence class [ main::p_y#0 ] +Added variable print::p to live range equivalence class [ print::p ] +Added variable get::i#0 to live range equivalence class [ get::i#0 ] +Added variable get::$0 to live range equivalence class [ get::$0 ] +Added variable main::p to live range equivalence class [ main::p ] +Added variable get::return to live range equivalence class [ get::return ] +Added variable get::p to live range equivalence class [ get::p ] Complete equivalence classes [ main::i#2 main::i#1 ] [ idx ] -[ print::p_x#0 ] -[ print::p_y#0 ] -[ get::return_x#0 ] -[ get::return_y#0 ] -[ main::p_x#0 ] -[ main::p_y#0 ] +[ print::p ] +[ get::i#0 ] +[ get::$0 ] +[ main::p ] +[ get::return ] +[ get::p ] Allocated zp[1]:2 [ main::i#2 main::i#1 ] Allocated zp[1]:3 [ idx ] -Allocated zp[1]:4 [ print::p_x#0 ] -Allocated zp[1]:5 [ print::p_y#0 ] -Allocated zp[1]:6 [ get::return_x#0 ] -Allocated zp[1]:7 [ get::return_y#0 ] -Allocated zp[1]:8 [ main::p_x#0 ] -Allocated zp[1]:9 [ main::p_y#0 ] +Allocated zp[2]:4 [ print::p ] +Allocated zp[1]:6 [ get::i#0 ] +Allocated zp[1]:7 [ get::$0 ] +Allocated zp[2]:8 [ main::p ] +Allocated zp[2]:10 [ get::return ] +Allocated zp[2]:12 [ get::p ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [1] idx = 0 [ idx ] ( [ idx ] { } ) always clobbers reg byte a -Statement [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:3::print:28 [ main::i#2 idx print::p_x#0 ] { } ) always clobbers reg byte a reg byte x +Statement [1] idx = 0 [ idx get::p get::return ] ( [ idx get::p get::return ] { } ) always clobbers reg byte a +Statement [5] print::p = stackidx(struct Point,print::OFFSET_STACK_P) [ idx print::p ] ( main:3::print:27 [ get::p get::return main::i#2 idx print::p ] { } ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [6] print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:3::print:28 [ main::i#2 idx print::p_x#0 print::p_y#0 ] { } ) always clobbers reg byte a reg byte x -Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::p_x#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:4 [ print::p_x#0 ] -Statement [7] SCREEN[idx] = print::p_x#0 [ idx print::p_y#0 ] ( main:3::print:28 [ main::i#2 idx print::p_y#0 ] { } ) always clobbers reg byte a reg byte y +Statement [6] SCREEN[idx] = *((byte*)&print::p) [ idx print::p ] ( main:3::print:27 [ get::p get::return main::i#2 idx print::p ] { } ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Removing always clobbered register reg byte a as potential for zp[1]:5 [ print::p_y#0 ] -Removing always clobbered register reg byte y as potential for zp[1]:5 [ print::p_y#0 ] -Statement [9] SCREEN[idx] = print::p_y#0 [ idx ] ( main:3::print:28 [ main::i#2 idx ] { } ) always clobbers reg byte a reg byte y -Statement [12] get::return_x#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::return_x#0 ] ( main:3::get:23 [ idx main::i#2 get::return_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [13] get::return_y#0 = get::return_x#0 >> 1 [ get::return_x#0 get::return_y#0 ] ( main:3::get:23 [ idx main::i#2 get::return_x#0 get::return_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:6 [ get::return_x#0 ] -Statement [14] stackidx(byte,0) = get::return_x#0 [ get::return_y#0 ] ( main:3::get:23 [ idx main::i#2 get::return_y#0 ] { } ) always clobbers reg byte a reg byte x -Removing always clobbered register reg byte a as potential for zp[1]:7 [ get::return_y#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:7 [ get::return_y#0 ] -Statement [15] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_y#0 [ ] ( main:3::get:23 [ idx main::i#2 ] { } ) always clobbers reg byte a reg byte x -Statement [19] if(main::i#2<5) goto main::@2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [21] stackpush(byte) = main::i#2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [24] main::p_x#0 = stackpull(byte) [ idx main::i#2 main::p_x#0 ] ( main:3 [ idx main::i#2 main::p_x#0 ] { } ) always clobbers reg byte a -Statement [25] main::p_y#0 = stackpull(byte) [ idx main::i#2 main::p_x#0 main::p_y#0 ] ( main:3 [ idx main::i#2 main::p_x#0 main::p_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:8 [ main::p_x#0 ] -Statement [26] stackpush(byte) = main::p_x#0 [ idx main::i#2 main::p_y#0 ] ( main:3 [ idx main::i#2 main::p_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:9 [ main::p_y#0 ] -Statement [27] stackpush(byte) = main::p_y#0 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a +Statement [8] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) [ idx ] ( main:3::print:27 [ get::p get::return main::i#2 idx ] { } ) always clobbers reg byte a reg byte y +Statement [11] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::i#0 get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::i#0 get::p get::return ] { } ) always clobbers reg byte a reg byte x +Statement [12] get::$0 = get::i#0 >> 1 [ get::i#0 get::$0 get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::i#0 get::$0 get::p get::return ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:6 [ get::i#0 ] +Statement [15] *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) [ get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::p get::return ] { } ) always clobbers reg byte a reg byte y +Statement [16] stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return [ get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::p get::return ] { } ) always clobbers reg byte a reg byte x +Statement [20] if(main::i#2<5) goto main::@2 [ idx get::p get::return main::i#2 ] ( main:3 [ idx get::p get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [22] stackpush(byte) = main::i#2 [ idx get::p get::return main::i#2 ] ( main:3 [ idx get::p get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [25] main::p = stackpull(struct Point) [ idx get::p get::return main::i#2 main::p ] ( main:3 [ idx get::p get::return main::i#2 main::p ] { } ) always clobbers reg byte a +Statement [26] stackpush(struct Point) = main::p [ idx get::p get::return main::i#2 ] ( main:3 [ idx get::p get::return main::i#2 ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(2) always clobbers reg byte a -Statement [1] idx = 0 [ idx ] ( [ idx ] { } ) always clobbers reg byte a -Statement [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:3::print:28 [ main::i#2 idx print::p_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [6] print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:3::print:28 [ main::i#2 idx print::p_x#0 print::p_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [7] SCREEN[idx] = print::p_x#0 [ idx print::p_y#0 ] ( main:3::print:28 [ main::i#2 idx print::p_y#0 ] { } ) always clobbers reg byte a reg byte y -Statement [9] SCREEN[idx] = print::p_y#0 [ idx ] ( main:3::print:28 [ main::i#2 idx ] { } ) always clobbers reg byte a reg byte y -Statement [12] get::return_x#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::return_x#0 ] ( main:3::get:23 [ idx main::i#2 get::return_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [13] get::return_y#0 = get::return_x#0 >> 1 [ get::return_x#0 get::return_y#0 ] ( main:3::get:23 [ idx main::i#2 get::return_x#0 get::return_y#0 ] { } ) always clobbers reg byte a -Statement [14] stackidx(byte,0) = get::return_x#0 [ get::return_y#0 ] ( main:3::get:23 [ idx main::i#2 get::return_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [15] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_y#0 [ ] ( main:3::get:23 [ idx main::i#2 ] { } ) always clobbers reg byte a reg byte x -Statement [19] if(main::i#2<5) goto main::@2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [21] stackpush(byte) = main::i#2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [24] main::p_x#0 = stackpull(byte) [ idx main::i#2 main::p_x#0 ] ( main:3 [ idx main::i#2 main::p_x#0 ] { } ) always clobbers reg byte a -Statement [25] main::p_y#0 = stackpull(byte) [ idx main::i#2 main::p_x#0 main::p_y#0 ] ( main:3 [ idx main::i#2 main::p_x#0 main::p_y#0 ] { } ) always clobbers reg byte a -Statement [26] stackpush(byte) = main::p_x#0 [ idx main::i#2 main::p_y#0 ] ( main:3 [ idx main::i#2 main::p_y#0 ] { } ) always clobbers reg byte a -Statement [27] stackpush(byte) = main::p_y#0 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a +Statement [1] idx = 0 [ idx get::p get::return ] ( [ idx get::p get::return ] { } ) always clobbers reg byte a +Statement [5] print::p = stackidx(struct Point,print::OFFSET_STACK_P) [ idx print::p ] ( main:3::print:27 [ get::p get::return main::i#2 idx print::p ] { } ) always clobbers reg byte a reg byte x +Statement [6] SCREEN[idx] = *((byte*)&print::p) [ idx print::p ] ( main:3::print:27 [ get::p get::return main::i#2 idx print::p ] { } ) always clobbers reg byte a reg byte y +Statement [8] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) [ idx ] ( main:3::print:27 [ get::p get::return main::i#2 idx ] { } ) always clobbers reg byte a reg byte y +Statement [11] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::i#0 get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::i#0 get::p get::return ] { } ) always clobbers reg byte a reg byte x +Statement [12] get::$0 = get::i#0 >> 1 [ get::i#0 get::$0 get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::i#0 get::$0 get::p get::return ] { } ) always clobbers reg byte a +Statement [15] *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) [ get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::p get::return ] { } ) always clobbers reg byte a reg byte y +Statement [16] stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return [ get::p get::return ] ( main:3::get:24 [ idx main::i#2 get::p get::return ] { } ) always clobbers reg byte a reg byte x +Statement [20] if(main::i#2<5) goto main::@2 [ idx get::p get::return main::i#2 ] ( main:3 [ idx get::p get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [22] stackpush(byte) = main::i#2 [ idx get::p get::return main::i#2 ] ( main:3 [ idx get::p get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [25] main::p = stackpull(struct Point) [ idx get::p get::return main::i#2 main::p ] ( main:3 [ idx get::p get::return main::i#2 main::p ] { } ) always clobbers reg byte a +Statement [26] stackpush(struct Point) = main::p [ idx get::p get::return main::i#2 ] ( main:3 [ idx get::p get::return main::i#2 ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(2) always clobbers reg byte a Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , Potential registers zp[1]:3 [ idx ] : zp[1]:3 , -Potential registers zp[1]:4 [ print::p_x#0 ] : zp[1]:4 , reg byte y , -Potential registers zp[1]:5 [ print::p_y#0 ] : zp[1]:5 , reg byte x , -Potential registers zp[1]:6 [ get::return_x#0 ] : zp[1]:6 , reg byte x , reg byte y , -Potential registers zp[1]:7 [ get::return_y#0 ] : zp[1]:7 , reg byte y , -Potential registers zp[1]:8 [ main::p_x#0 ] : zp[1]:8 , reg byte x , reg byte y , -Potential registers zp[1]:9 [ main::p_y#0 ] : zp[1]:9 , reg byte x , reg byte y , +Potential registers zp[2]:4 [ print::p ] : zp[2]:4 , +Potential registers zp[1]:6 [ get::i#0 ] : zp[1]:6 , reg byte x , reg byte y , +Potential registers zp[1]:7 [ get::$0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:8 [ main::p ] : zp[2]:8 , +Potential registers zp[2]:10 [ get::return ] : zp[2]:10 , +Potential registers zp[2]:12 [ get::p ] : zp[2]:12 , REGISTER UPLIFT SCOPES -Uplift Scope [get] 1,501.5: zp[1]:6 [ get::return_x#0 ] 1,001: zp[1]:7 [ get::return_y#0 ] -Uplift Scope [print] 1,001: zp[1]:4 [ print::p_x#0 ] 667.33: zp[1]:5 [ print::p_y#0 ] -Uplift Scope [main] 238.73: zp[1]:2 [ main::i#2 main::i#1 ] 101: zp[1]:8 [ main::p_x#0 ] 101: zp[1]:9 [ main::p_y#0 ] -Uplift Scope [] 273.09: zp[1]:3 [ idx ] +Uplift Scope [get] 1,501.5: zp[1]:6 [ get::i#0 ] 1,001: zp[1]:7 [ get::$0 ] 47.67: zp[2]:10 [ get::return ] 0: zp[2]:12 [ get::p ] +Uplift Scope [main] 246.89: zp[1]:2 [ main::i#2 main::i#1 ] 202: zp[2]:8 [ main::p ] +Uplift Scope [print] 333.67: zp[2]:4 [ print::p ] +Uplift Scope [] 316.21: zp[1]:3 [ idx ] Uplift Scope [Point] Uplift Scope [__start] -Uplifting [get] best 974 combination reg byte x [ get::return_x#0 ] reg byte y [ get::return_y#0 ] -Uplifting [print] best 970 combination reg byte y [ print::p_x#0 ] reg byte x [ print::p_y#0 ] -Uplifting [main] best 930 combination zp[1]:2 [ main::i#2 main::i#1 ] reg byte y [ main::p_x#0 ] reg byte x [ main::p_y#0 ] -Uplifting [] best 930 combination zp[1]:3 [ idx ] -Uplifting [Point] best 930 combination -Uplifting [__start] best 930 combination +Uplifting [get] best 995 combination reg byte x [ get::i#0 ] reg byte a [ get::$0 ] zp[2]:10 [ get::return ] zp[2]:12 [ get::p ] +Uplifting [main] best 995 combination zp[1]:2 [ main::i#2 main::i#1 ] zp[2]:8 [ main::p ] +Uplifting [print] best 995 combination zp[2]:4 [ print::p ] +Uplifting [] best 995 combination zp[1]:3 [ idx ] +Uplifting [Point] best 995 combination +Uplifting [__start] best 995 combination Attempting to uplift remaining variables inzp[1]:3 [ idx ] -Uplifting [] best 930 combination zp[1]:3 [ idx ] +Uplifting [] best 995 combination zp[1]:3 [ idx ] Attempting to uplift remaining variables inzp[1]:2 [ main::i#2 main::i#1 ] -Uplifting [main] best 930 combination zp[1]:2 [ main::i#2 main::i#1 ] +Uplifting [main] best 995 combination zp[1]:2 [ main::i#2 main::i#1 ] +Coalescing zero page register [ zp[2]:8 [ main::p ] ] with [ zp[2]:4 [ print::p ] ] +Allocated (was zp[2]:8) zp[2]:4 [ main::p print::p ] +Allocated (was zp[2]:10) zp[2]:6 [ get::return ] +Allocated (was zp[2]:12) zp[2]:8 [ get::p ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -392,8 +339,9 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Basic :BasicUpstart(__start) // Global Constants & labels - .const STACK_BASE = $103 .const OFFSET_STRUCT_POINT_Y = 1 + .const SIZEOF_STRUCT_POINT = 2 + .const STACK_BASE = $103 .label SCREEN = $400 .label idx = 3 .segment Code @@ -419,112 +367,121 @@ __start: { rts } // print -// print(byte register(Y) p_x, byte register(X) p_y) +// print(struct Point zp(4) p) print: { - .const OFFSET_STACK_P_X = 1 - .const OFFSET_STACK_P_Y = 0 - // [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1 + .const OFFSET_STACK_P = 0 + .label p = 4 + // [5] print::p = stackidx(struct Point,print::OFFSET_STACK_P) -- vssz1=_stackidxstruct_2_vbuc1 tsx - lda STACK_BASE+OFFSET_STACK_P_X,x - tay - // [6] print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) -- vbuxx=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_P_Y,x - tax - // [7] SCREEN[idx] = print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuyy - tya + lda STACK_BASE+OFFSET_STACK_P,x + sta.z p + lda STACK_BASE+OFFSET_STACK_P+1,x + sta.z p+1 + // [6] SCREEN[idx] = *((byte*)&print::p) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda.z p ldy.z idx sta SCREEN,y - // [8] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [7] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx - // [9] SCREEN[idx] = print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuxx + // [8] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda p+OFFSET_STRUCT_POINT_Y ldy.z idx - txa sta SCREEN,y - // [10] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [9] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx jmp __breturn // print::@return __breturn: - // [11] return + // [10] return rts } // get +// get(byte register(X) i) get: { .const OFFSET_STACK_I = 0 - // [12] get::return_x#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1 + .const OFFSET_STACK_RETURN_0 = 0 + .label return = 6 + .label p = 8 + // [11] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_I,x tax - // [13] get::return_y#0 = get::return_x#0 >> 1 -- vbuyy=vbuxx_ror_1 + // [12] get::$0 = get::i#0 >> 1 -- vbuaa=vbuxx_ror_1 txa lsr - tay + // [13] *((byte*)&get::p) = get::i#0 -- _deref_pbuc1=vbuxx + stx.z p + // [14] *((byte*)&get::p+OFFSET_STRUCT_POINT_Y) = get::$0 -- _deref_pbuc1=vbuaa + sta p+OFFSET_STRUCT_POINT_Y + // [15] *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_POINT + !: + lda p-1,y + sta return-1,y + dey + bne !- jmp __breturn // get::@return __breturn: - // [14] stackidx(byte,0) = get::return_x#0 -- _stackidxbyte_vbuc1=vbuxx - txa + // [16] stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return -- _stackidxstruct_2_vbuc1=vssz1 tsx - sta STACK_BASE+0,x - // [15] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_y#0 -- _stackidxbyte_vbuc1=vbuyy - tya - tsx - sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x - // [16] return + lda.z return + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + lda.z return+1 + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x + // [17] return rts } // main main: { + .label p = 4 .label i = 2 - // [18] phi from main to main::@1 [phi:main->main::@1] + // [19] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [18] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + // [19] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 sta.z i jmp __b1 // main::@1 __b1: - // [19] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + // [20] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z i cmp #5 bcc __b2 jmp __breturn // main::@return __breturn: - // [20] return + // [21] return rts // main::@2 __b2: - // [21] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + // [22] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 lda.z i pha // sideeffect stackpushbytes(1) -- _stackpushbyte_1 pha - // [23] callexecute get -- jsr + // [24] callexecute get -- jsr jsr get - // [24] main::p_x#0 = stackpull(byte) -- vbuyy=_stackpullbyte_ + // [25] main::p = stackpull(struct Point) -- vssz1=_stackpullstruct_2_ pla - tay - // [25] main::p_y#0 = stackpull(byte) -- vbuxx=_stackpullbyte_ + sta.z p pla - tax - // [26] stackpush(byte) = main::p_x#0 -- _stackpushbyte_=vbuyy - tya + sta.z p+1 + // [26] stackpush(struct Point) = main::p -- _stackpushstruct_2_=vssz1 + lda.z p+1 pha - // [27] stackpush(byte) = main::p_y#0 -- _stackpushbyte_=vbuxx - txa + lda.z p pha - // [28] callexecute print -- jsr + // [27] callexecute print -- jsr jsr print // sideeffect stackpullbytes(2) -- _stackpullbyte_2 pla pla - // [30] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + // [29] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 inc.z i - // [18] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [19] phi from main::@2 to main::@1 [phi:main::@2->main::@1] __b1_from___b2: - // [18] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy + // [19] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 } // File Data @@ -538,6 +495,8 @@ Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda.z p+1 +Succesful ASM optimization Pass5UnnecesaryLoadElimination Removing instruction __b1_from___init1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __init1: @@ -553,48 +512,38 @@ Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE constant byte OFFSET_STRUCT_POINT_Y = 1 constant byte* const SCREEN = (byte*) 1024 +constant byte SIZEOF_STRUCT_POINT = 2 constant word STACK_BASE = $103 void __start() __stackcall struct Point get(byte get::i) +byte~ get::$0 reg byte a 1001.0 constant byte get::OFFSET_STACK_I = 0 +constant byte get::OFFSET_STACK_RETURN_0 = 0 byte get::i -byte get::p_x -byte get::p_y -struct Point get::return -byte get::return_x -byte get::return_x#0 reg byte x 1501.5 -byte get::return_y -byte get::return_y#0 reg byte y 1001.0 -byte idx loadstore zp[1]:3 273.0909090909091 +byte get::i#0 reg byte x 1501.5 +struct Point get::p loadstore zp[2]:8 +struct Point get::return loadstore zp[2]:6 47.666666666666664 +byte idx loadstore zp[1]:3 316.2105263157895 __stackcall void main() byte main::i byte main::i#1 i zp[1]:2 202.0 -byte main::i#2 i zp[1]:2 36.72727272727273 -struct Point main::p -byte main::p_x -byte main::p_x#0 reg byte y 101.0 -byte main::p_y -byte main::p_y#0 reg byte x 101.0 -__stackcall void print(byte print::p_x , byte print::p_y) -constant byte print::OFFSET_STACK_P_X = 1 -constant byte print::OFFSET_STACK_P_Y = 0 -byte print::p_x -byte print::p_x#0 reg byte y 1001.0 -byte print::p_y -byte print::p_y#0 reg byte x 667.3333333333334 +byte main::i#2 i zp[1]:2 44.888888888888886 +struct Point main::p loadstore zp[2]:4 202.0 +__stackcall void print(struct Point print::p) +constant byte print::OFFSET_STACK_P = 0 +struct Point print::p loadstore zp[2]:4 333.6666666666667 zp[1]:2 [ main::i#2 main::i#1 ] zp[1]:3 [ idx ] -reg byte y [ print::p_x#0 ] -reg byte x [ print::p_y#0 ] -reg byte x [ get::return_x#0 ] -reg byte y [ get::return_y#0 ] -reg byte y [ main::p_x#0 ] -reg byte x [ main::p_y#0 ] +reg byte x [ get::i#0 ] +reg byte a [ get::$0 ] +zp[2]:4 [ main::p print::p ] +zp[2]:6 [ get::return ] +zp[2]:8 [ get::p ] FINAL ASSEMBLER -Score: 828 +Score: 863 // File Comments // Test a procedure with calling convention stack @@ -609,8 +558,9 @@ Score: 828 .segment Basic :BasicUpstart(__start) // Global Constants & labels - .const STACK_BASE = $103 .const OFFSET_STRUCT_POINT_Y = 1 + .const SIZEOF_STRUCT_POINT = 2 + .const STACK_BASE = $103 .label SCREEN = $400 .label idx = 3 .segment Code @@ -630,115 +580,125 @@ __start: { rts } // print -// print(byte register(Y) p_x, byte register(X) p_y) +// print(struct Point zp(4) p) print: { - .const OFFSET_STACK_P_X = 1 - .const OFFSET_STACK_P_Y = 0 - // [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1 + .const OFFSET_STACK_P = 0 + .label p = 4 + // [5] print::p = stackidx(struct Point,print::OFFSET_STACK_P) -- vssz1=_stackidxstruct_2_vbuc1 tsx - lda STACK_BASE+OFFSET_STACK_P_X,x - tay - // [6] print::p_y#0 = stackidx(byte,print::OFFSET_STACK_P_Y) -- vbuxx=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_P_Y,x - tax + lda STACK_BASE+OFFSET_STACK_P,x + sta.z p + lda STACK_BASE+OFFSET_STACK_P+1,x + sta.z p+1 // SCREEN[idx++] = p.x - // [7] SCREEN[idx] = print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuyy - tya + // [6] SCREEN[idx] = *((byte*)&print::p) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda.z p ldy.z idx sta SCREEN,y // SCREEN[idx++] = p.x; - // [8] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [7] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // SCREEN[idx++] = p.y - // [9] SCREEN[idx] = print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuxx + // [8] SCREEN[idx] = *((byte*)&print::p+OFFSET_STRUCT_POINT_Y) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda p+OFFSET_STRUCT_POINT_Y ldy.z idx - txa sta SCREEN,y // SCREEN[idx++] = p.y; - // [10] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [9] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // print::@return // } - // [11] return + // [10] return rts } // get +// get(byte register(X) i) get: { .const OFFSET_STACK_I = 0 - // [12] get::return_x#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1 + .const OFFSET_STACK_RETURN_0 = 0 + .label return = 6 + .label p = 8 + // [11] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_I,x tax // i/2 - // [13] get::return_y#0 = get::return_x#0 >> 1 -- vbuyy=vbuxx_ror_1 + // [12] get::$0 = get::i#0 >> 1 -- vbuaa=vbuxx_ror_1 txa lsr - tay + // struct Point p = { i, i/2 } + // [13] *((byte*)&get::p) = get::i#0 -- _deref_pbuc1=vbuxx + stx.z p + // [14] *((byte*)&get::p+OFFSET_STRUCT_POINT_Y) = get::$0 -- _deref_pbuc1=vbuaa + sta p+OFFSET_STRUCT_POINT_Y + // return p; + // [15] *(&get::return) = memcpy(*(&get::p), struct Point, SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_POINT + !: + lda p-1,y + sta return-1,y + dey + bne !- // get::@return // } - // [14] stackidx(byte,0) = get::return_x#0 -- _stackidxbyte_vbuc1=vbuxx - txa + // [16] stackidx(struct Point,get::OFFSET_STACK_RETURN_0) = get::return -- _stackidxstruct_2_vbuc1=vssz1 tsx - sta STACK_BASE+0,x - // [15] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_y#0 -- _stackidxbyte_vbuc1=vbuyy - tya - tsx - sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x - // [16] return + lda.z return + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + lda.z return+1 + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x + // [17] return rts } // main main: { + .label p = 4 .label i = 2 - // [18] phi from main to main::@1 [phi:main->main::@1] - // [18] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + // [19] phi from main to main::@1 [phi:main->main::@1] + // [19] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 sta.z i // main::@1 __b1: // for(char i=0;i<5;i++) - // [19] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + // [20] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z i cmp #5 bcc __b2 // main::@return // } - // [20] return + // [21] return rts // main::@2 __b2: // struct Point p = get(i) - // [21] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + // [22] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 lda.z i pha // sideeffect stackpushbytes(1) -- _stackpushbyte_1 pha - // [23] callexecute get -- jsr + // [24] callexecute get -- jsr jsr get - // [24] main::p_x#0 = stackpull(byte) -- vbuyy=_stackpullbyte_ + // [25] main::p = stackpull(struct Point) -- vssz1=_stackpullstruct_2_ pla - tay - // [25] main::p_y#0 = stackpull(byte) -- vbuxx=_stackpullbyte_ + sta.z p pla - tax + sta.z p+1 // print(p) - // [26] stackpush(byte) = main::p_x#0 -- _stackpushbyte_=vbuyy - tya + // [26] stackpush(struct Point) = main::p -- _stackpushstruct_2_=vssz1 pha - // [27] stackpush(byte) = main::p_y#0 -- _stackpushbyte_=vbuxx - txa + lda.z p pha - // [28] callexecute print -- jsr + // [27] callexecute print -- jsr jsr print // sideeffect stackpullbytes(2) -- _stackpullbyte_2 pla pla // for(char i=0;i<5;i++) - // [30] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + // [29] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 inc.z i - // [18] phi from main::@2 to main::@1 [phi:main::@2->main::@1] - // [18] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy + // [19] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [19] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-10.sym b/src/test/ref/procedure-callingconvention-stack-10.sym index 10c15ea98..979bd9cd0 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.sym +++ b/src/test/ref/procedure-callingconvention-stack-10.sym @@ -1,40 +1,30 @@ constant byte OFFSET_STRUCT_POINT_Y = 1 constant byte* const SCREEN = (byte*) 1024 +constant byte SIZEOF_STRUCT_POINT = 2 constant word STACK_BASE = $103 void __start() __stackcall struct Point get(byte get::i) +byte~ get::$0 reg byte a 1001.0 constant byte get::OFFSET_STACK_I = 0 +constant byte get::OFFSET_STACK_RETURN_0 = 0 byte get::i -byte get::p_x -byte get::p_y -struct Point get::return -byte get::return_x -byte get::return_x#0 reg byte x 1501.5 -byte get::return_y -byte get::return_y#0 reg byte y 1001.0 -byte idx loadstore zp[1]:3 273.0909090909091 +byte get::i#0 reg byte x 1501.5 +struct Point get::p loadstore zp[2]:8 +struct Point get::return loadstore zp[2]:6 47.666666666666664 +byte idx loadstore zp[1]:3 316.2105263157895 __stackcall void main() byte main::i byte main::i#1 i zp[1]:2 202.0 -byte main::i#2 i zp[1]:2 36.72727272727273 -struct Point main::p -byte main::p_x -byte main::p_x#0 reg byte y 101.0 -byte main::p_y -byte main::p_y#0 reg byte x 101.0 -__stackcall void print(byte print::p_x , byte print::p_y) -constant byte print::OFFSET_STACK_P_X = 1 -constant byte print::OFFSET_STACK_P_Y = 0 -byte print::p_x -byte print::p_x#0 reg byte y 1001.0 -byte print::p_y -byte print::p_y#0 reg byte x 667.3333333333334 +byte main::i#2 i zp[1]:2 44.888888888888886 +struct Point main::p loadstore zp[2]:4 202.0 +__stackcall void print(struct Point print::p) +constant byte print::OFFSET_STACK_P = 0 +struct Point print::p loadstore zp[2]:4 333.6666666666667 zp[1]:2 [ main::i#2 main::i#1 ] zp[1]:3 [ idx ] -reg byte y [ print::p_x#0 ] -reg byte x [ print::p_y#0 ] -reg byte x [ get::return_x#0 ] -reg byte y [ get::return_y#0 ] -reg byte y [ main::p_x#0 ] -reg byte x [ main::p_y#0 ] +reg byte x [ get::i#0 ] +reg byte a [ get::$0 ] +zp[2]:4 [ main::p print::p ] +zp[2]:6 [ get::return ] +zp[2]:8 [ get::p ] diff --git a/src/test/ref/procedure-callingconvention-stack-11.asm b/src/test/ref/procedure-callingconvention-stack-11.asm index ec7b27738..3ac266043 100644 --- a/src/test/ref/procedure-callingconvention-stack-11.asm +++ b/src/test/ref/procedure-callingconvention-stack-11.asm @@ -8,9 +8,10 @@ .segmentdef Data [startAfter="Code"] .segment Basic :BasicUpstart(__start) - .const STACK_BASE = $103 .const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const SIZEOF_STRUCT_VECTOR = 4 + .const STACK_BASE = $103 .label SCREEN = $400 .label idx = 3 .segment Code @@ -21,47 +22,40 @@ __start: { jsr main rts } -// print(byte register(Y) v_p1_x, byte zp(4) v_p1_y, byte zp(5) v_p2_x, byte register(X) v_p2_y) +// print(struct Vector zp(6) v) print: { - .const OFFSET_STACK_V_P1_X = 3 - .const OFFSET_STACK_V_P1_Y = 2 - .const OFFSET_STACK_V_P2_X = 1 - .const OFFSET_STACK_V_P2_Y = 0 - .label v_p1_y = 4 - .label v_p2_x = 5 + .const OFFSET_STACK_V = 0 + .label v = 6 tsx - lda STACK_BASE+OFFSET_STACK_V_P1_X,x - tay - tsx - lda STACK_BASE+OFFSET_STACK_V_P1_Y,x - sta.z v_p1_y - tsx - lda STACK_BASE+OFFSET_STACK_V_P2_X,x - sta.z v_p2_x - tsx - lda STACK_BASE+OFFSET_STACK_V_P2_Y,x - tax + lda STACK_BASE+OFFSET_STACK_V,x + sta.z v + lda STACK_BASE+OFFSET_STACK_V+1,x + sta.z v+1 + lda STACK_BASE+OFFSET_STACK_V+2,x + sta.z v+2 + lda STACK_BASE+OFFSET_STACK_V+3,x + sta.z v+3 // SCREEN[idx++] = v.p1.x - tya + lda.z v ldy.z idx sta SCREEN,y // SCREEN[idx++] = v.p1.x; inc.z idx // SCREEN[idx++] = v.p1.y - lda.z v_p1_y + lda v+OFFSET_STRUCT_POINT_Y ldy.z idx sta SCREEN,y // SCREEN[idx++] = v.p1.y; inc.z idx // SCREEN[idx++] = v.p2.x - lda.z v_p2_x + lda v+OFFSET_STRUCT_VECTOR_P2 ldy.z idx sta SCREEN,y // SCREEN[idx++] = v.p2.x; inc.z idx // SCREEN[idx++] = v.p2.y + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y ldy.z idx - txa sta SCREEN,y // SCREEN[idx++] = v.p2.y; inc.z idx @@ -74,43 +68,57 @@ print: { // } rts } +// get(byte register(Y) i) get: { .const OFFSET_STACK_I = 0 - .label return_p1_y = 4 - .label return_p2_y = 5 + .const OFFSET_STACK_RETURN_0 = 0 + .label return = $a + .label v = $e + .label __0 = 4 + .label __2 = 5 tsx lda STACK_BASE+OFFSET_STACK_I,x - tax - // i/2 - txa - lsr - sta.z return_p1_y - // i+1 - txa tay - iny - // i*2 - txa - asl - sta.z return_p2_y - // } - txa - tsx - sta STACK_BASE+0,x - lda.z return_p1_y - tsx - sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x + // i/2 tya + lsr + sta.z __0 + // i+1 + tya + tax + inx + // i*2 + tya + asl + sta.z __2 + // struct Vector v = { {i, i/2}, {i+1, i*2} } + sty.z v + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + stx v+OFFSET_STRUCT_VECTOR_P2 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // return v; + ldy #SIZEOF_STRUCT_VECTOR + !: + lda v-1,y + sta return-1,y + dey + bne !- + // } tsx - sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x - lda.z return_p2_y - tsx - sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x + lda.z return + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + lda.z return+1 + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x + lda.z return+2 + sta STACK_BASE+OFFSET_STACK_RETURN_0+2,x + lda.z return+3 + sta STACK_BASE+OFFSET_STACK_RETURN_0+3,x rts } main: { - .label v_p2_x = 4 - .label v_p2_y = 5 + .label v = 6 .label i = 2 lda #0 sta.z i @@ -130,21 +138,20 @@ main: { pha jsr get pla - tay + sta.z v pla - tax + sta.z v+1 pla - sta.z v_p2_x + sta.z v+2 pla - sta.z v_p2_y + sta.z v+3 // print(v) - tya pha - txa + lda.z v+2 pha - lda.z v_p2_x + lda.z v+1 pha - lda.z v_p2_y + lda.z v pha jsr print tsx diff --git a/src/test/ref/procedure-callingconvention-stack-11.cfg b/src/test/ref/procedure-callingconvention-stack-11.cfg index 20fe80e6e..76df66019 100644 --- a/src/test/ref/procedure-callingconvention-stack-11.cfg +++ b/src/test/ref/procedure-callingconvention-stack-11.cfg @@ -14,66 +14,59 @@ __start::@return: scope:[__start] from __start::@1 [4] return to:@return -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) +__stackcall void print(struct Vector print::v) print: scope:[print] from - [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) - [6] print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) - [7] print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) - [8] print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) - [9] SCREEN[idx] = print::v_p1_x#0 - [10] idx = ++ idx - [11] SCREEN[idx] = print::v_p1_y#0 - [12] idx = ++ idx - [13] SCREEN[idx] = print::v_p2_x#0 - [14] idx = ++ idx - [15] SCREEN[idx] = print::v_p2_y#0 - [16] idx = ++ idx - [17] SCREEN[idx] = ' ' - [18] idx = ++ idx + [5] print::v = stackidx(struct Vector,print::OFFSET_STACK_V) + [6] SCREEN[idx] = *((byte*)(struct Point*)&print::v) + [7] idx = ++ idx + [8] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_POINT_Y) + [9] idx = ++ idx + [10] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2) + [11] idx = ++ idx + [12] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) + [13] idx = ++ idx + [14] SCREEN[idx] = ' ' + [15] idx = ++ idx to:print::@return print::@return: scope:[print] from print - [19] return + [16] return to:@return __stackcall struct Vector get(byte get::i) get: scope:[get] from - [20] get::return_p1_x#0 = stackidx(byte,get::OFFSET_STACK_I) - [21] get::return_p1_y#0 = get::return_p1_x#0 >> 1 - [22] get::return_p2_x#0 = get::return_p1_x#0 + 1 - [23] get::return_p2_y#0 = get::return_p1_x#0 << 1 + [17] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) + [18] get::$0 = get::i#0 >> 1 + [19] get::$1 = get::i#0 + 1 + [20] get::$2 = get::i#0 << 1 + [21] *((byte*)(struct Point*)&get::v) = get::i#0 + [22] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_POINT_Y) = get::$0 + [23] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2) = get::$1 + [24] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::$2 + [25] *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) to:get::@return get::@return: scope:[get] from get - [24] stackidx(byte,0) = get::return_p1_x#0 - [25] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 - [26] stackidx(byte,OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 - [27] stackidx(byte,OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 - [28] return + [26] stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return + [27] return to:@return __stackcall void main() main: scope:[main] from - [29] phi() + [28] phi() to:main::@1 main::@1: scope:[main] from main main::@2 - [30] main::i#2 = phi( main/0, main::@2/main::i#1 ) - [31] if(main::i#2<5) goto main::@2 + [29] main::i#2 = phi( main/0, main::@2/main::i#1 ) + [30] if(main::i#2<5) goto main::@2 to:main::@return main::@return: scope:[main] from main::@1 - [32] return + [31] return to:@return main::@2: scope:[main] from main::@1 - [33] stackpush(byte) = main::i#2 + [32] stackpush(byte) = main::i#2 sideeffect stackpushbytes(3) - [35] callexecute get - [36] main::v_p1_x#0 = stackpull(byte) - [37] main::v_p1_y#0 = stackpull(byte) - [38] main::v_p2_x#0 = stackpull(byte) - [39] main::v_p2_y#0 = stackpull(byte) - [40] stackpush(byte) = main::v_p1_x#0 - [41] stackpush(byte) = main::v_p1_y#0 - [42] stackpush(byte) = main::v_p2_x#0 - [43] stackpush(byte) = main::v_p2_y#0 - [44] callexecute print + [34] callexecute get + [35] main::v = stackpull(struct Vector) + [36] stackpush(struct Vector) = main::v + [37] callexecute print sideeffect stackpullbytes(4) - [46] main::i#1 = ++ main::i#2 + [39] main::i#1 = ++ main::i#2 to:main::@1 diff --git a/src/test/ref/procedure-callingconvention-stack-11.log b/src/test/ref/procedure-callingconvention-stack-11.log index 4cd349658..00c9a9f51 100644 --- a/src/test/ref/procedure-callingconvention-stack-11.log +++ b/src/test/ref/procedure-callingconvention-stack-11.log @@ -3,27 +3,17 @@ Adding parameter assignment in __stackcall procedure get::i = param(get::i) Adding parameter assignment in __stackcall procedure print::v = param(print::v) Inlined call call __init Eliminating unused variable with no statement main::$1 -Calling convention __stackcall adding prepare/execute/finalize for { { main::v_p1_x, main::v_p1_y }, { main::v_p2_x, main::v_p2_y } } = call get main::i -Calling convention __stackcall adding prepare/execute/finalize for call print main::v_p1_x main::v_p1_y main::v_p2_x main::v_p2_y +Calling convention __stackcall adding prepare/execute/finalize for main::v = call get main::i +Calling convention __stackcall adding prepare/execute/finalize for call print main::v Calling convention __stackcall adding prepare/execute/finalize for call main Calling convention STACK_CALL replacing param(get::i) with stackidx(byte,get::OFFSET_STACK_I) -Calling convention STACK_CALL replacing param(print::v_p1_x) with stackidx(byte,print::OFFSET_STACK_V_P1_X) -Calling convention STACK_CALL replacing param(print::v_p1_y) with stackidx(byte,print::OFFSET_STACK_V_P1_Y) -Calling convention STACK_CALL replacing param(print::v_p2_x) with stackidx(byte,print::OFFSET_STACK_V_P2_X) -Calling convention STACK_CALL replacing param(print::v_p2_y) with stackidx(byte,print::OFFSET_STACK_V_P2_Y) -Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) = get::return_p1_x -Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) = get::return_p1_y -Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) = get::return_p2_x -Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y -Calling convention STACK_CALL adding stack pull main::v_p1_x = stackpull(byte) -Calling convention STACK_CALL adding stack pull main::v_p1_y = stackpull(byte) -Calling convention STACK_CALL adding stack pull main::v_p2_x = stackpull(byte) -Calling convention STACK_CALL adding stack pull main::v_p2_y = stackpull(byte) +Calling convention STACK_CALL replacing param(print::v) with stackidx(struct Vector,print::OFFSET_STACK_V) +Calling convention STACK_CALL adding stack return stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return +Calling convention STACK_CALL adding stack pull main::v = stackpull(struct Vector) Calling convention STACK_CALL adding stack push stackpush(byte) = main::i -Calling convention STACK_CALL adding stack push stackpush(byte) = main::v_p1_x -Calling convention STACK_CALL adding stack push stackpush(byte) = main::v_p1_y -Calling convention STACK_CALL adding stack push stackpush(byte) = main::v_p2_x -Calling convention STACK_CALL adding stack push stackpush(byte) = main::v_p2_y +Calling convention STACK_CALL adding stack push stackpush(struct Vector) = main::v +Removing C-classic struct-unwound assignment get::v = struct-unwound {*((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y), *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y)} +Removing C-classic struct-unwound assignment get::return = struct-unwound {*(&get::return)} CONTROL FLOW GRAPH SSA @@ -41,14 +31,8 @@ main::@2: scope:[main] from main::@1 stackpush(byte) = main::i#3 sideeffect stackpushbytes(3) callexecute get - main::v_p1_x#0 = stackpull(byte) - main::v_p1_y#0 = stackpull(byte) - main::v_p2_x#0 = stackpull(byte) - main::v_p2_y#0 = stackpull(byte) - stackpush(byte) = main::v_p1_x#0 - stackpush(byte) = main::v_p1_y#0 - stackpush(byte) = main::v_p2_x#0 - stackpush(byte) = main::v_p2_y#0 + main::v = stackpull(struct Vector) + stackpush(struct Vector) = main::v callexecute print sideeffect stackpullbytes(4) main::i#1 = ++ main::i#3 @@ -63,41 +47,27 @@ get: scope:[get] from get::$0 = get::i#0 / 2 get::$1 = get::i#0 + 1 get::$2 = get::i#0 * 2 - get::v_p1_x#0 = get::i#0 - get::v_p1_y#0 = get::$0 - get::v_p2_x#0 = get::$1 - get::v_p2_y#0 = get::$2 - get::return_p1_x#0 = get::v_p1_x#0 - get::return_p1_y#0 = get::v_p1_y#0 - get::return_p2_x#0 = get::v_p2_x#0 - get::return_p2_y#0 = get::v_p2_y#0 - get::return#0 = struct-unwound {get::return_p1_x#0, get::return_p1_y#0, get::return_p2_x#0, get::return_p2_y#0} + *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) = get::i#0 + *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) = get::$0 + *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) = get::$1 + *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::$2 + *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) to:get::@return get::@return: scope:[get] from get - get::return_p2_y#1 = phi( get/get::return_p2_y#0 ) - get::return_p2_x#1 = phi( get/get::return_p2_x#0 ) - get::return_p1_y#1 = phi( get/get::return_p1_y#0 ) - get::return_p1_x#1 = phi( get/get::return_p1_x#0 ) - stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) = get::return_p1_x#1 - stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) = get::return_p1_y#1 - stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) = get::return_p2_x#1 - stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#1 + stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return return to:@return -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) +__stackcall void print(struct Vector print::v) print: scope:[print] from - print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) - print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) - print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) - print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) - SCREEN[idx] = print::v_p1_x#0 + print::v = stackidx(struct Vector,print::OFFSET_STACK_V) + SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) idx = ++ idx - SCREEN[idx] = print::v_p1_y#0 + SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) idx = ++ idx - SCREEN[idx] = print::v_p2_x#0 + SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) idx = ++ idx - SCREEN[idx] = print::v_p2_y#0 + SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) idx = ++ idx SCREEN[idx] = ' ' idx = ++ idx @@ -125,6 +95,7 @@ constant byte OFFSET_STRUCT_POINT_Y = 1 constant byte OFFSET_STRUCT_VECTOR_P1 = 0 constant byte OFFSET_STRUCT_VECTOR_P2 = 2 constant byte* const SCREEN = (byte*)$400 +constant byte SIZEOF_STRUCT_VECTOR = 4 constant word STACK_BASE = $103 void __start() __stackcall struct Vector get(byte get::i) @@ -132,35 +103,11 @@ number~ get::$0 number~ get::$1 number~ get::$2 constant byte get::OFFSET_STACK_I = 0 -constant byte get::OFFSET_STACK_RETURN = 0 +constant byte get::OFFSET_STACK_RETURN_0 = 0 byte get::i byte get::i#0 -struct Vector get::return -struct Vector get::return#0 -struct Point get::return_p1 -byte get::return_p1_x -byte get::return_p1_x#0 -byte get::return_p1_x#1 -byte get::return_p1_y -byte get::return_p1_y#0 -byte get::return_p1_y#1 -struct Point get::return_p2 -byte get::return_p2_x -byte get::return_p2_x#0 -byte get::return_p2_x#1 -byte get::return_p2_y -byte get::return_p2_y#0 -byte get::return_p2_y#1 -struct Point get::v_p1 -byte get::v_p1_x -byte get::v_p1_x#0 -byte get::v_p1_y -byte get::v_p1_y#0 -struct Point get::v_p2 -byte get::v_p2_x -byte get::v_p2_x#0 -byte get::v_p2_y -byte get::v_p2_y#0 +struct Vector get::return loadstore +struct Vector get::v loadstore byte idx loadstore __stackcall void main() bool~ main::$0 @@ -169,32 +116,10 @@ byte main::i#0 byte main::i#1 byte main::i#2 byte main::i#3 -struct Vector main::v -struct Point main::v_p1 -byte main::v_p1_x -byte main::v_p1_x#0 -byte main::v_p1_y -byte main::v_p1_y#0 -struct Point main::v_p2 -byte main::v_p2_x -byte main::v_p2_x#0 -byte main::v_p2_y -byte main::v_p2_y#0 -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) -constant byte print::OFFSET_STACK_V_P1_X = 3 -constant byte print::OFFSET_STACK_V_P1_Y = 2 -constant byte print::OFFSET_STACK_V_P2_X = 1 -constant byte print::OFFSET_STACK_V_P2_Y = 0 -struct Point print::v_p1 -byte print::v_p1_x -byte print::v_p1_x#0 -byte print::v_p1_y -byte print::v_p1_y#0 -struct Point print::v_p2 -byte print::v_p2_x -byte print::v_p2_x#0 -byte print::v_p2_y -byte print::v_p2_y#0 +struct Vector main::v loadstore +__stackcall void print(struct Vector print::v) +constant byte print::OFFSET_STACK_V = 0 +struct Vector print::v loadstore Adding number conversion cast (unumber) 5 in main::$0 = main::i#2 < 5 Adding number conversion cast (unumber) 2 in get::$0 = get::i#0 / 2 @@ -219,31 +144,25 @@ Inferred type updated to byte in get::$0 = get::i#0 / 2 Inferred type updated to byte in get::$1 = get::i#0 + 1 Inferred type updated to byte in get::$2 = get::i#0 * 2 Alias main::i#2 = main::i#3 -Alias get::return_p1_x#0 = get::v_p1_x#0 get::i#0 get::return_p1_x#1 -Alias get::return_p1_y#0 = get::v_p1_y#0 get::$0 get::return_p1_y#1 -Alias get::return_p2_x#0 = get::v_p2_x#0 get::$1 get::return_p2_x#1 -Alias get::return_p2_y#0 = get::v_p2_y#0 get::$2 get::return_p2_y#1 Successful SSA optimization Pass2AliasElimination Simple Condition main::$0 [3] if(main::i#2<5) goto main::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Constant main::i#0 = 0 Successful SSA optimization Pass2ConstantIdentification -Simplifying constant evaluating to zero get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X in [24] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) = get::return_p1_x#0 -Simplifying constant evaluating to zero get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1 in [25] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 -Successful SSA optimization PassNSimplifyConstantZero -Simplifying expression containing zero OFFSET_STRUCT_POINT_Y in [25] stackidx(byte,0+OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 -Simplifying expression containing zero get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2 in [26] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) = get::return_p2_x#0 -Simplifying expression containing zero OFFSET_STRUCT_VECTOR_P2 in [27] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 +Simplifying expression containing zero (byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1 in [17] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) = get::i#0 +Simplifying expression containing zero (struct Point*)&get::v in [17] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1) = get::i#0 +Simplifying expression containing zero (struct Point*)&get::v in [18] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) = get::$0 +Simplifying expression containing zero (byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2 in [19] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) = get::$1 +Simplifying expression containing zero (byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P1 in [25] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero (struct Point*)&print::v in [25] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P1) +Simplifying expression containing zero (struct Point*)&print::v in [27] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) +Simplifying expression containing zero (byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2 in [29] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) Successful SSA optimization PassNSimplifyExpressionWithZero -Simplifying expression containing zero OFFSET_STRUCT_VECTOR_P2 in [26] stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 -Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable get::return#0 and assignment [21] get::return#0 = struct-unwound {get::return_p1_x#0, get::return_p1_y#0, get::return_p2_x#0, get::return_p2_y#0} -Eliminating unused constant get::OFFSET_STACK_RETURN Eliminating unused constant OFFSET_STRUCT_VECTOR_P1 Eliminating unused constant OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars -Rewriting division to use shift [18] get::return_p1_y#0 = get::return_p1_x#0 / 2 -Rewriting multiplication to use shift [20] get::return_p2_y#0 = get::return_p1_x#0 * 2 +Rewriting division to use shift [12] get::$0 = get::i#0 / 2 +Rewriting multiplication to use shift [14] get::$2 = get::i#0 * 2 Successful SSA optimization Pass2MultiplyToShiftRewriting Inlining constant with var siblings main::i#0 Constant inlined main::i#0 = 0 @@ -256,10 +175,10 @@ Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of main CALL GRAPH Calls in [__start] to main:3 -Calls in [main] to get:35 print:44 +Calls in [main] to get:34 print:37 Created 1 initial phi equivalence classes -Coalesced [47] main::i#4 = main::i#1 +Coalesced [40] main::i#4 = main::i#1 Coalesced down to 1 phi equivalence classes Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 @@ -282,68 +201,61 @@ __start::@return: scope:[__start] from __start::@1 [4] return to:@return -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) +__stackcall void print(struct Vector print::v) print: scope:[print] from - [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) - [6] print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) - [7] print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) - [8] print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) - [9] SCREEN[idx] = print::v_p1_x#0 - [10] idx = ++ idx - [11] SCREEN[idx] = print::v_p1_y#0 - [12] idx = ++ idx - [13] SCREEN[idx] = print::v_p2_x#0 - [14] idx = ++ idx - [15] SCREEN[idx] = print::v_p2_y#0 - [16] idx = ++ idx - [17] SCREEN[idx] = ' ' - [18] idx = ++ idx + [5] print::v = stackidx(struct Vector,print::OFFSET_STACK_V) + [6] SCREEN[idx] = *((byte*)(struct Point*)&print::v) + [7] idx = ++ idx + [8] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_POINT_Y) + [9] idx = ++ idx + [10] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2) + [11] idx = ++ idx + [12] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) + [13] idx = ++ idx + [14] SCREEN[idx] = ' ' + [15] idx = ++ idx to:print::@return print::@return: scope:[print] from print - [19] return + [16] return to:@return __stackcall struct Vector get(byte get::i) get: scope:[get] from - [20] get::return_p1_x#0 = stackidx(byte,get::OFFSET_STACK_I) - [21] get::return_p1_y#0 = get::return_p1_x#0 >> 1 - [22] get::return_p2_x#0 = get::return_p1_x#0 + 1 - [23] get::return_p2_y#0 = get::return_p1_x#0 << 1 + [17] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) + [18] get::$0 = get::i#0 >> 1 + [19] get::$1 = get::i#0 + 1 + [20] get::$2 = get::i#0 << 1 + [21] *((byte*)(struct Point*)&get::v) = get::i#0 + [22] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_POINT_Y) = get::$0 + [23] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2) = get::$1 + [24] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::$2 + [25] *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) to:get::@return get::@return: scope:[get] from get - [24] stackidx(byte,0) = get::return_p1_x#0 - [25] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 - [26] stackidx(byte,OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 - [27] stackidx(byte,OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 - [28] return + [26] stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return + [27] return to:@return __stackcall void main() main: scope:[main] from - [29] phi() + [28] phi() to:main::@1 main::@1: scope:[main] from main main::@2 - [30] main::i#2 = phi( main/0, main::@2/main::i#1 ) - [31] if(main::i#2<5) goto main::@2 + [29] main::i#2 = phi( main/0, main::@2/main::i#1 ) + [30] if(main::i#2<5) goto main::@2 to:main::@return main::@return: scope:[main] from main::@1 - [32] return + [31] return to:@return main::@2: scope:[main] from main::@1 - [33] stackpush(byte) = main::i#2 + [32] stackpush(byte) = main::i#2 sideeffect stackpushbytes(3) - [35] callexecute get - [36] main::v_p1_x#0 = stackpull(byte) - [37] main::v_p1_y#0 = stackpull(byte) - [38] main::v_p2_x#0 = stackpull(byte) - [39] main::v_p2_y#0 = stackpull(byte) - [40] stackpush(byte) = main::v_p1_x#0 - [41] stackpush(byte) = main::v_p1_y#0 - [42] stackpush(byte) = main::v_p2_x#0 - [43] stackpush(byte) = main::v_p2_y#0 - [44] callexecute print + [34] callexecute get + [35] main::v = stackpull(struct Vector) + [36] stackpush(struct Vector) = main::v + [37] callexecute print sideeffect stackpullbytes(4) - [46] main::i#1 = ++ main::i#2 + [39] main::i#1 = ++ main::i#2 to:main::@1 null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 main::@1 in scope print @@ -352,230 +264,137 @@ null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 VARIABLE REGISTER WEIGHTS void __start() __stackcall struct Vector get(byte get::i) +byte~ get::$0 500.5 +byte~ get::$1 500.5 +byte~ get::$2 500.5 byte get::i -struct Vector get::return -struct Point get::return_p1 -byte get::return_p1_x -byte get::return_p1_x#0 1251.25 -byte get::return_p1_y -byte get::return_p1_y#0 500.5 -struct Point get::return_p2 -byte get::return_p2_x -byte get::return_p2_x#0 500.5 -byte get::return_p2_y -byte get::return_p2_y#0 500.5 -struct Point get::v_p1 -byte get::v_p1_x -byte get::v_p1_y -struct Point get::v_p2 -byte get::v_p2_x -byte get::v_p2_y -byte idx loadstore 441.67647058823525 +byte get::i#0 1251.25 +struct Vector get::return loadstore 40.04 +struct Vector get::v loadstore +byte idx loadstore 600.68 __stackcall void main() byte main::i byte main::i#1 202.0 -byte main::i#2 26.933333333333334 -struct Vector main::v -struct Point main::v_p1 -byte main::v_p1_x -byte main::v_p1_x#0 50.5 -byte main::v_p1_y -byte main::v_p1_y#0 50.5 -struct Point main::v_p2 -byte main::v_p2_x -byte main::v_p2_x#0 50.5 -byte main::v_p2_y -byte main::v_p2_y#0 50.5 -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) -struct Point print::v_p1 -byte print::v_p1_x -byte print::v_p1_x#0 500.5 -byte print::v_p1_y -byte print::v_p1_y#0 400.4 -struct Point print::v_p2 -byte print::v_p2_x -byte print::v_p2_x#0 333.6666666666667 -byte print::v_p2_y -byte print::v_p2_y#0 286.0 +byte main::i#2 44.888888888888886 +struct Vector main::v loadstore 202.0 +__stackcall void print(struct Vector print::v) +struct Vector print::v loadstore 143.0 Initial phi equivalence classes [ main::i#2 main::i#1 ] Added variable idx to live range equivalence class [ idx ] -Added variable print::v_p1_x#0 to live range equivalence class [ print::v_p1_x#0 ] -Added variable print::v_p1_y#0 to live range equivalence class [ print::v_p1_y#0 ] -Added variable print::v_p2_x#0 to live range equivalence class [ print::v_p2_x#0 ] -Added variable print::v_p2_y#0 to live range equivalence class [ print::v_p2_y#0 ] -Added variable get::return_p1_x#0 to live range equivalence class [ get::return_p1_x#0 ] -Added variable get::return_p1_y#0 to live range equivalence class [ get::return_p1_y#0 ] -Added variable get::return_p2_x#0 to live range equivalence class [ get::return_p2_x#0 ] -Added variable get::return_p2_y#0 to live range equivalence class [ get::return_p2_y#0 ] -Added variable main::v_p1_x#0 to live range equivalence class [ main::v_p1_x#0 ] -Added variable main::v_p1_y#0 to live range equivalence class [ main::v_p1_y#0 ] -Added variable main::v_p2_x#0 to live range equivalence class [ main::v_p2_x#0 ] -Added variable main::v_p2_y#0 to live range equivalence class [ main::v_p2_y#0 ] +Added variable print::v to live range equivalence class [ print::v ] +Added variable get::i#0 to live range equivalence class [ get::i#0 ] +Added variable get::$0 to live range equivalence class [ get::$0 ] +Added variable get::$1 to live range equivalence class [ get::$1 ] +Added variable get::$2 to live range equivalence class [ get::$2 ] +Added variable main::v to live range equivalence class [ main::v ] +Added variable get::return to live range equivalence class [ get::return ] +Added variable get::v to live range equivalence class [ get::v ] Complete equivalence classes [ main::i#2 main::i#1 ] [ idx ] -[ print::v_p1_x#0 ] -[ print::v_p1_y#0 ] -[ print::v_p2_x#0 ] -[ print::v_p2_y#0 ] -[ get::return_p1_x#0 ] -[ get::return_p1_y#0 ] -[ get::return_p2_x#0 ] -[ get::return_p2_y#0 ] -[ main::v_p1_x#0 ] -[ main::v_p1_y#0 ] -[ main::v_p2_x#0 ] -[ main::v_p2_y#0 ] +[ print::v ] +[ get::i#0 ] +[ get::$0 ] +[ get::$1 ] +[ get::$2 ] +[ main::v ] +[ get::return ] +[ get::v ] Allocated zp[1]:2 [ main::i#2 main::i#1 ] Allocated zp[1]:3 [ idx ] -Allocated zp[1]:4 [ print::v_p1_x#0 ] -Allocated zp[1]:5 [ print::v_p1_y#0 ] -Allocated zp[1]:6 [ print::v_p2_x#0 ] -Allocated zp[1]:7 [ print::v_p2_y#0 ] -Allocated zp[1]:8 [ get::return_p1_x#0 ] -Allocated zp[1]:9 [ get::return_p1_y#0 ] -Allocated zp[1]:10 [ get::return_p2_x#0 ] -Allocated zp[1]:11 [ get::return_p2_y#0 ] -Allocated zp[1]:12 [ main::v_p1_x#0 ] -Allocated zp[1]:13 [ main::v_p1_y#0 ] -Allocated zp[1]:14 [ main::v_p2_x#0 ] -Allocated zp[1]:15 [ main::v_p2_y#0 ] +Allocated zp[4]:4 [ print::v ] +Allocated zp[1]:8 [ get::i#0 ] +Allocated zp[1]:9 [ get::$0 ] +Allocated zp[1]:10 [ get::$1 ] +Allocated zp[1]:11 [ get::$2 ] +Allocated zp[4]:12 [ main::v ] +Allocated zp[4]:16 [ get::return ] +Allocated zp[4]:20 [ get::v ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [1] idx = 0 [ idx ] ( [ idx ] { } ) always clobbers reg byte a -Statement [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) [ idx print::v_p1_x#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 ] { } ) always clobbers reg byte a reg byte x +Statement [1] idx = 0 [ idx get::v get::return ] ( [ idx get::v get::return ] { } ) always clobbers reg byte a +Statement [5] print::v = stackidx(struct Vector,print::OFFSET_STACK_V) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Statement [6] print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 print::v_p1_y#0 ] { } ) always clobbers reg byte a reg byte x -Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::v_p1_x#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:4 [ print::v_p1_x#0 ] -Statement [7] print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] { } ) always clobbers reg byte a reg byte x -Removing always clobbered register reg byte a as potential for zp[1]:5 [ print::v_p1_y#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:5 [ print::v_p1_y#0 ] -Statement [8] print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Removing always clobbered register reg byte a as potential for zp[1]:6 [ print::v_p2_x#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:6 [ print::v_p2_x#0 ] -Statement [9] SCREEN[idx] = print::v_p1_x#0 [ idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte y +Statement [6] SCREEN[idx] = *((byte*)(struct Point*)&print::v) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Removing always clobbered register reg byte y as potential for zp[1]:5 [ print::v_p1_y#0 ] -Removing always clobbered register reg byte y as potential for zp[1]:6 [ print::v_p2_x#0 ] -Removing always clobbered register reg byte a as potential for zp[1]:7 [ print::v_p2_y#0 ] -Removing always clobbered register reg byte y as potential for zp[1]:7 [ print::v_p2_y#0 ] -Statement [11] SCREEN[idx] = print::v_p1_y#0 [ idx print::v_p2_x#0 print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p2_x#0 print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte y -Statement [13] SCREEN[idx] = print::v_p2_x#0 [ idx print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte y -Statement [15] SCREEN[idx] = print::v_p2_y#0 [ idx ] ( main:3::print:44 [ main::i#2 idx ] { } ) always clobbers reg byte a reg byte y -Statement [17] SCREEN[idx] = ' ' [ idx ] ( main:3::print:44 [ main::i#2 idx ] { } ) always clobbers reg byte a reg byte y -Statement [20] get::return_p1_x#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::return_p1_x#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [21] get::return_p1_y#0 = get::return_p1_x#0 >> 1 [ get::return_p1_x#0 get::return_p1_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_x#0 get::return_p1_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:8 [ get::return_p1_x#0 ] -Statement [23] get::return_p2_y#0 = get::return_p1_x#0 << 1 [ get::return_p1_x#0 get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_x#0 get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:9 [ get::return_p1_y#0 ] -Removing always clobbered register reg byte a as potential for zp[1]:10 [ get::return_p2_x#0 ] -Statement [24] stackidx(byte,0) = get::return_p1_x#0 [ get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Removing always clobbered register reg byte x as potential for zp[1]:9 [ get::return_p1_y#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:10 [ get::return_p2_x#0 ] -Removing always clobbered register reg byte a as potential for zp[1]:11 [ get::return_p2_y#0 ] -Removing always clobbered register reg byte x as potential for zp[1]:11 [ get::return_p2_y#0 ] -Statement [25] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 [ get::return_p2_x#0 get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p2_x#0 get::return_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [26] stackidx(byte,OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 [ get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [27] stackidx(byte,OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 [ ] ( main:3::get:35 [ idx main::i#2 ] { } ) always clobbers reg byte a reg byte x -Statement [31] if(main::i#2<5) goto main::@2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [33] stackpush(byte) = main::i#2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [36] main::v_p1_x#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 ] { } ) always clobbers reg byte a -Statement [37] main::v_p1_y#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:12 [ main::v_p1_x#0 ] -Statement [38] main::v_p2_x#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:13 [ main::v_p1_y#0 ] -Statement [39] main::v_p2_y#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:14 [ main::v_p2_x#0 ] -Statement [40] stackpush(byte) = main::v_p1_x#0 [ idx main::i#2 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:15 [ main::v_p2_y#0 ] -Statement [41] stackpush(byte) = main::v_p1_y#0 [ idx main::i#2 main::v_p2_x#0 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p2_x#0 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Statement [42] stackpush(byte) = main::v_p2_x#0 [ idx main::i#2 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Statement [43] stackpush(byte) = main::v_p2_y#0 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a +Statement [8] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_POINT_Y) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte y +Statement [10] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte y +Statement [12] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) [ idx ] ( main:3::print:37 [ get::v get::return main::i#2 idx ] { } ) always clobbers reg byte a reg byte y +Statement [14] SCREEN[idx] = ' ' [ idx ] ( main:3::print:37 [ get::v get::return main::i#2 idx ] { } ) always clobbers reg byte a reg byte y +Statement [17] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::i#0 get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::i#0 get::v get::return ] { } ) always clobbers reg byte a reg byte x +Statement [18] get::$0 = get::i#0 >> 1 [ get::i#0 get::$0 get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::i#0 get::$0 get::v get::return ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:8 [ get::i#0 ] +Statement [20] get::$2 = get::i#0 << 1 [ get::i#0 get::$0 get::$1 get::$2 get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::i#0 get::$0 get::$1 get::$2 get::v get::return ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:9 [ get::$0 ] +Removing always clobbered register reg byte a as potential for zp[1]:10 [ get::$1 ] +Statement [25] *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) [ get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::v get::return ] { } ) always clobbers reg byte a reg byte y +Statement [26] stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return [ get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::v get::return ] { } ) always clobbers reg byte a reg byte x +Statement [30] if(main::i#2<5) goto main::@2 [ idx get::v get::return main::i#2 ] ( main:3 [ idx get::v get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [32] stackpush(byte) = main::i#2 [ idx get::v get::return main::i#2 ] ( main:3 [ idx get::v get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [35] main::v = stackpull(struct Vector) [ idx get::v get::return main::i#2 main::v ] ( main:3 [ idx get::v get::return main::i#2 main::v ] { } ) always clobbers reg byte a +Statement [36] stackpush(struct Vector) = main::v [ idx get::v get::return main::i#2 ] ( main:3 [ idx get::v get::return main::i#2 ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(4) always clobbers reg byte a reg byte x -Statement [1] idx = 0 [ idx ] ( [ idx ] { } ) always clobbers reg byte a -Statement [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) [ idx print::v_p1_x#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [6] print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 print::v_p1_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [7] print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [8] print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [9] SCREEN[idx] = print::v_p1_x#0 [ idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte y -Statement [11] SCREEN[idx] = print::v_p1_y#0 [ idx print::v_p2_x#0 print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p2_x#0 print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte y -Statement [13] SCREEN[idx] = print::v_p2_x#0 [ idx print::v_p2_y#0 ] ( main:3::print:44 [ main::i#2 idx print::v_p2_y#0 ] { } ) always clobbers reg byte a reg byte y -Statement [15] SCREEN[idx] = print::v_p2_y#0 [ idx ] ( main:3::print:44 [ main::i#2 idx ] { } ) always clobbers reg byte a reg byte y -Statement [17] SCREEN[idx] = ' ' [ idx ] ( main:3::print:44 [ main::i#2 idx ] { } ) always clobbers reg byte a reg byte y -Statement [20] get::return_p1_x#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::return_p1_x#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_x#0 ] { } ) always clobbers reg byte a reg byte x -Statement [21] get::return_p1_y#0 = get::return_p1_x#0 >> 1 [ get::return_p1_x#0 get::return_p1_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_x#0 get::return_p1_y#0 ] { } ) always clobbers reg byte a -Statement [23] get::return_p2_y#0 = get::return_p1_x#0 << 1 [ get::return_p1_x#0 get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_x#0 get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] { } ) always clobbers reg byte a -Statement [24] stackidx(byte,0) = get::return_p1_x#0 [ get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [25] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 [ get::return_p2_x#0 get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p2_x#0 get::return_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [26] stackidx(byte,OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 [ get::return_p2_y#0 ] ( main:3::get:35 [ idx main::i#2 get::return_p2_y#0 ] { } ) always clobbers reg byte a reg byte x -Statement [27] stackidx(byte,OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 [ ] ( main:3::get:35 [ idx main::i#2 ] { } ) always clobbers reg byte a reg byte x -Statement [31] if(main::i#2<5) goto main::@2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [33] stackpush(byte) = main::i#2 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a -Statement [36] main::v_p1_x#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 ] { } ) always clobbers reg byte a -Statement [37] main::v_p1_y#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 ] { } ) always clobbers reg byte a -Statement [38] main::v_p2_x#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 ] { } ) always clobbers reg byte a -Statement [39] main::v_p2_y#0 = stackpull(byte) [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p1_x#0 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Statement [40] stackpush(byte) = main::v_p1_x#0 [ idx main::i#2 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p1_y#0 main::v_p2_x#0 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Statement [41] stackpush(byte) = main::v_p1_y#0 [ idx main::i#2 main::v_p2_x#0 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p2_x#0 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Statement [42] stackpush(byte) = main::v_p2_x#0 [ idx main::i#2 main::v_p2_y#0 ] ( main:3 [ idx main::i#2 main::v_p2_y#0 ] { } ) always clobbers reg byte a -Statement [43] stackpush(byte) = main::v_p2_y#0 [ idx main::i#2 ] ( main:3 [ idx main::i#2 ] { } ) always clobbers reg byte a +Statement [1] idx = 0 [ idx get::v get::return ] ( [ idx get::v get::return ] { } ) always clobbers reg byte a +Statement [5] print::v = stackidx(struct Vector,print::OFFSET_STACK_V) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte x +Statement [6] SCREEN[idx] = *((byte*)(struct Point*)&print::v) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte y +Statement [8] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_POINT_Y) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte y +Statement [10] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2) [ idx print::v ] ( main:3::print:37 [ get::v get::return main::i#2 idx print::v ] { } ) always clobbers reg byte a reg byte y +Statement [12] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) [ idx ] ( main:3::print:37 [ get::v get::return main::i#2 idx ] { } ) always clobbers reg byte a reg byte y +Statement [14] SCREEN[idx] = ' ' [ idx ] ( main:3::print:37 [ get::v get::return main::i#2 idx ] { } ) always clobbers reg byte a reg byte y +Statement [17] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) [ get::i#0 get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::i#0 get::v get::return ] { } ) always clobbers reg byte a reg byte x +Statement [18] get::$0 = get::i#0 >> 1 [ get::i#0 get::$0 get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::i#0 get::$0 get::v get::return ] { } ) always clobbers reg byte a +Statement [20] get::$2 = get::i#0 << 1 [ get::i#0 get::$0 get::$1 get::$2 get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::i#0 get::$0 get::$1 get::$2 get::v get::return ] { } ) always clobbers reg byte a +Statement [25] *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) [ get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::v get::return ] { } ) always clobbers reg byte a reg byte y +Statement [26] stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return [ get::v get::return ] ( main:3::get:34 [ idx main::i#2 get::v get::return ] { } ) always clobbers reg byte a reg byte x +Statement [30] if(main::i#2<5) goto main::@2 [ idx get::v get::return main::i#2 ] ( main:3 [ idx get::v get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [32] stackpush(byte) = main::i#2 [ idx get::v get::return main::i#2 ] ( main:3 [ idx get::v get::return main::i#2 ] { } ) always clobbers reg byte a +Statement [35] main::v = stackpull(struct Vector) [ idx get::v get::return main::i#2 main::v ] ( main:3 [ idx get::v get::return main::i#2 main::v ] { } ) always clobbers reg byte a +Statement [36] stackpush(struct Vector) = main::v [ idx get::v get::return main::i#2 ] ( main:3 [ idx get::v get::return main::i#2 ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(4) always clobbers reg byte a reg byte x Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , Potential registers zp[1]:3 [ idx ] : zp[1]:3 , -Potential registers zp[1]:4 [ print::v_p1_x#0 ] : zp[1]:4 , reg byte y , -Potential registers zp[1]:5 [ print::v_p1_y#0 ] : zp[1]:5 , -Potential registers zp[1]:6 [ print::v_p2_x#0 ] : zp[1]:6 , -Potential registers zp[1]:7 [ print::v_p2_y#0 ] : zp[1]:7 , reg byte x , -Potential registers zp[1]:8 [ get::return_p1_x#0 ] : zp[1]:8 , reg byte x , reg byte y , -Potential registers zp[1]:9 [ get::return_p1_y#0 ] : zp[1]:9 , reg byte y , -Potential registers zp[1]:10 [ get::return_p2_x#0 ] : zp[1]:10 , reg byte y , -Potential registers zp[1]:11 [ get::return_p2_y#0 ] : zp[1]:11 , reg byte y , -Potential registers zp[1]:12 [ main::v_p1_x#0 ] : zp[1]:12 , reg byte x , reg byte y , -Potential registers zp[1]:13 [ main::v_p1_y#0 ] : zp[1]:13 , reg byte x , reg byte y , -Potential registers zp[1]:14 [ main::v_p2_x#0 ] : zp[1]:14 , reg byte x , reg byte y , -Potential registers zp[1]:15 [ main::v_p2_y#0 ] : zp[1]:15 , reg byte x , reg byte y , +Potential registers zp[4]:4 [ print::v ] : zp[4]:4 , +Potential registers zp[1]:8 [ get::i#0 ] : zp[1]:8 , reg byte x , reg byte y , +Potential registers zp[1]:9 [ get::$0 ] : zp[1]:9 , reg byte x , reg byte y , +Potential registers zp[1]:10 [ get::$1 ] : zp[1]:10 , reg byte x , reg byte y , +Potential registers zp[1]:11 [ get::$2 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y , +Potential registers zp[4]:12 [ main::v ] : zp[4]:12 , +Potential registers zp[4]:16 [ get::return ] : zp[4]:16 , +Potential registers zp[4]:20 [ get::v ] : zp[4]:20 , REGISTER UPLIFT SCOPES -Uplift Scope [get] 1,251.25: zp[1]:8 [ get::return_p1_x#0 ] 500.5: zp[1]:9 [ get::return_p1_y#0 ] 500.5: zp[1]:10 [ get::return_p2_x#0 ] 500.5: zp[1]:11 [ get::return_p2_y#0 ] -Uplift Scope [print] 500.5: zp[1]:4 [ print::v_p1_x#0 ] 400.4: zp[1]:5 [ print::v_p1_y#0 ] 333.67: zp[1]:6 [ print::v_p2_x#0 ] 286: zp[1]:7 [ print::v_p2_y#0 ] -Uplift Scope [] 441.68: zp[1]:3 [ idx ] -Uplift Scope [main] 228.93: zp[1]:2 [ main::i#2 main::i#1 ] 50.5: zp[1]:12 [ main::v_p1_x#0 ] 50.5: zp[1]:13 [ main::v_p1_y#0 ] 50.5: zp[1]:14 [ main::v_p2_x#0 ] 50.5: zp[1]:15 [ main::v_p2_y#0 ] +Uplift Scope [get] 1,251.25: zp[1]:8 [ get::i#0 ] 500.5: zp[1]:9 [ get::$0 ] 500.5: zp[1]:10 [ get::$1 ] 500.5: zp[1]:11 [ get::$2 ] 40.04: zp[4]:16 [ get::return ] 0: zp[4]:20 [ get::v ] +Uplift Scope [] 600.68: zp[1]:3 [ idx ] +Uplift Scope [main] 246.89: zp[1]:2 [ main::i#2 main::i#1 ] 202: zp[4]:12 [ main::v ] +Uplift Scope [print] 143: zp[4]:4 [ print::v ] Uplift Scope [Point] Uplift Scope [Vector] Uplift Scope [__start] -Uplifting [get] best 1393 combination reg byte x [ get::return_p1_x#0 ] zp[1]:9 [ get::return_p1_y#0 ] reg byte y [ get::return_p2_x#0 ] zp[1]:11 [ get::return_p2_y#0 ] -Uplifting [print] best 1389 combination reg byte y [ print::v_p1_x#0 ] zp[1]:5 [ print::v_p1_y#0 ] zp[1]:6 [ print::v_p2_x#0 ] reg byte x [ print::v_p2_y#0 ] -Uplifting [] best 1389 combination zp[1]:3 [ idx ] -Uplifting [main] best 1349 combination zp[1]:2 [ main::i#2 main::i#1 ] reg byte y [ main::v_p1_x#0 ] reg byte x [ main::v_p1_y#0 ] zp[1]:14 [ main::v_p2_x#0 ] zp[1]:15 [ main::v_p2_y#0 ] -Uplifting [Point] best 1349 combination -Uplifting [Vector] best 1349 combination -Uplifting [__start] best 1349 combination -Attempting to uplift remaining variables inzp[1]:9 [ get::return_p1_y#0 ] -Uplifting [get] best 1349 combination zp[1]:9 [ get::return_p1_y#0 ] -Attempting to uplift remaining variables inzp[1]:11 [ get::return_p2_y#0 ] -Uplifting [get] best 1349 combination zp[1]:11 [ get::return_p2_y#0 ] +Uplifting [get] best 1425 combination reg byte y [ get::i#0 ] zp[1]:9 [ get::$0 ] reg byte x [ get::$1 ] zp[1]:11 [ get::$2 ] zp[4]:16 [ get::return ] zp[4]:20 [ get::v ] +Limited combination testing to 100 combinations of 108 possible. +Uplifting [] best 1425 combination zp[1]:3 [ idx ] +Uplifting [main] best 1425 combination zp[1]:2 [ main::i#2 main::i#1 ] zp[4]:12 [ main::v ] +Uplifting [print] best 1425 combination zp[4]:4 [ print::v ] +Uplifting [Point] best 1425 combination +Uplifting [Vector] best 1425 combination +Uplifting [__start] best 1425 combination Attempting to uplift remaining variables inzp[1]:3 [ idx ] -Uplifting [] best 1349 combination zp[1]:3 [ idx ] -Attempting to uplift remaining variables inzp[1]:5 [ print::v_p1_y#0 ] -Uplifting [print] best 1349 combination zp[1]:5 [ print::v_p1_y#0 ] -Attempting to uplift remaining variables inzp[1]:6 [ print::v_p2_x#0 ] -Uplifting [print] best 1349 combination zp[1]:6 [ print::v_p2_x#0 ] +Uplifting [] best 1425 combination zp[1]:3 [ idx ] +Attempting to uplift remaining variables inzp[1]:9 [ get::$0 ] +Uplifting [get] best 1425 combination zp[1]:9 [ get::$0 ] +Attempting to uplift remaining variables inzp[1]:11 [ get::$2 ] +Uplifting [get] best 1425 combination zp[1]:11 [ get::$2 ] Attempting to uplift remaining variables inzp[1]:2 [ main::i#2 main::i#1 ] -Uplifting [main] best 1349 combination zp[1]:2 [ main::i#2 main::i#1 ] -Attempting to uplift remaining variables inzp[1]:14 [ main::v_p2_x#0 ] -Uplifting [main] best 1349 combination zp[1]:14 [ main::v_p2_x#0 ] -Attempting to uplift remaining variables inzp[1]:15 [ main::v_p2_y#0 ] -Uplifting [main] best 1349 combination zp[1]:15 [ main::v_p2_y#0 ] -Coalescing zero page register [ zp[1]:9 [ get::return_p1_y#0 ] ] with [ zp[1]:5 [ print::v_p1_y#0 ] ] -Coalescing zero page register [ zp[1]:11 [ get::return_p2_y#0 ] ] with [ zp[1]:6 [ print::v_p2_x#0 ] ] -Coalescing zero page register [ zp[1]:14 [ main::v_p2_x#0 ] ] with [ zp[1]:9 [ get::return_p1_y#0 print::v_p1_y#0 ] ] -Coalescing zero page register [ zp[1]:15 [ main::v_p2_y#0 ] ] with [ zp[1]:11 [ get::return_p2_y#0 print::v_p2_x#0 ] ] -Allocated (was zp[1]:14) zp[1]:4 [ main::v_p2_x#0 get::return_p1_y#0 print::v_p1_y#0 ] -Allocated (was zp[1]:15) zp[1]:5 [ main::v_p2_y#0 get::return_p2_y#0 print::v_p2_x#0 ] +Uplifting [main] best 1425 combination zp[1]:2 [ main::i#2 main::i#1 ] +Coalescing zero page register [ zp[4]:12 [ main::v ] ] with [ zp[4]:4 [ print::v ] ] +Allocated (was zp[1]:9) zp[1]:4 [ get::$0 ] +Allocated (was zp[1]:11) zp[1]:5 [ get::$2 ] +Allocated (was zp[4]:12) zp[4]:6 [ main::v print::v ] +Allocated (was zp[4]:16) zp[4]:10 [ get::return ] +Allocated (was zp[4]:20) zp[4]:14 [ get::v ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -591,9 +410,10 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Basic :BasicUpstart(__start) // Global Constants & labels - .const STACK_BASE = $103 .const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const SIZEOF_STRUCT_VECTOR = 4 + .const STACK_BASE = $103 .label SCREEN = $400 .label idx = 3 .segment Code @@ -619,178 +439,176 @@ __start: { rts } // print -// print(byte register(Y) v_p1_x, byte zp(4) v_p1_y, byte zp(5) v_p2_x, byte register(X) v_p2_y) +// print(struct Vector zp(6) v) print: { - .const OFFSET_STACK_V_P1_X = 3 - .const OFFSET_STACK_V_P1_Y = 2 - .const OFFSET_STACK_V_P2_X = 1 - .const OFFSET_STACK_V_P2_Y = 0 - .label v_p1_y = 4 - .label v_p2_x = 5 - // [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) -- vbuyy=_stackidxbyte_vbuc1 + .const OFFSET_STACK_V = 0 + .label v = 6 + // [5] print::v = stackidx(struct Vector,print::OFFSET_STACK_V) -- vssz1=_stackidxstruct_4_vbuc1 tsx - lda STACK_BASE+OFFSET_STACK_V_P1_X,x - tay - // [6] print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) -- vbuz1=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_V_P1_Y,x - sta.z v_p1_y - // [7] print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) -- vbuz1=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_V_P2_X,x - sta.z v_p2_x - // [8] print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) -- vbuxx=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_V_P2_Y,x - tax - // [9] SCREEN[idx] = print::v_p1_x#0 -- pbuc1_derefidx_vbuz1=vbuyy - tya + lda STACK_BASE+OFFSET_STACK_V,x + sta.z v + lda STACK_BASE+OFFSET_STACK_V+1,x + sta.z v+1 + lda STACK_BASE+OFFSET_STACK_V+2,x + sta.z v+2 + lda STACK_BASE+OFFSET_STACK_V+3,x + sta.z v+3 + // [6] SCREEN[idx] = *((byte*)(struct Point*)&print::v) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda.z v ldy.z idx sta SCREEN,y - // [10] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [7] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx - // [11] SCREEN[idx] = print::v_p1_y#0 -- pbuc1_derefidx_vbuz1=vbuz2 - lda.z v_p1_y + // [8] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_POINT_Y) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda v+OFFSET_STRUCT_POINT_Y ldy.z idx sta SCREEN,y - // [12] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [9] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx - // [13] SCREEN[idx] = print::v_p2_x#0 -- pbuc1_derefidx_vbuz1=vbuz2 - lda.z v_p2_x + // [10] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda v+OFFSET_STRUCT_VECTOR_P2 ldy.z idx sta SCREEN,y - // [14] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [11] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx - // [15] SCREEN[idx] = print::v_p2_y#0 -- pbuc1_derefidx_vbuz1=vbuxx + // [12] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y ldy.z idx - txa sta SCREEN,y - // [16] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [13] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx - // [17] SCREEN[idx] = ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + // [14] SCREEN[idx] = ' ' -- pbuc1_derefidx_vbuz1=vbuc2 lda #' ' ldy.z idx sta SCREEN,y - // [18] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [15] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx jmp __breturn // print::@return __breturn: - // [19] return + // [16] return rts } // get +// get(byte register(Y) i) get: { .const OFFSET_STACK_I = 0 - .label return_p1_y = 4 - .label return_p2_y = 5 - // [20] get::return_p1_x#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1 + .const OFFSET_STACK_RETURN_0 = 0 + .label return = $a + .label v = $e + .label __0 = 4 + .label __2 = 5 + // [17] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuyy=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_I,x - tax - // [21] get::return_p1_y#0 = get::return_p1_x#0 >> 1 -- vbuz1=vbuxx_ror_1 - txa - lsr - sta.z return_p1_y - // [22] get::return_p2_x#0 = get::return_p1_x#0 + 1 -- vbuyy=vbuxx_plus_1 - txa tay - iny - // [23] get::return_p2_y#0 = get::return_p1_x#0 << 1 -- vbuz1=vbuxx_rol_1 - txa + // [18] get::$0 = get::i#0 >> 1 -- vbuz1=vbuyy_ror_1 + tya + lsr + sta.z __0 + // [19] get::$1 = get::i#0 + 1 -- vbuxx=vbuyy_plus_1 + tya + tax + inx + // [20] get::$2 = get::i#0 << 1 -- vbuz1=vbuyy_rol_1 + tya asl - sta.z return_p2_y + sta.z __2 + // [21] *((byte*)(struct Point*)&get::v) = get::i#0 -- _deref_pbuc1=vbuyy + sty.z v + // [22] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_POINT_Y) = get::$0 -- _deref_pbuc1=vbuz1 + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + // [23] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2) = get::$1 -- _deref_pbuc1=vbuxx + stx v+OFFSET_STRUCT_VECTOR_P2 + // [24] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::$2 -- _deref_pbuc1=vbuz1 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // [25] *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_VECTOR + !: + lda v-1,y + sta return-1,y + dey + bne !- jmp __breturn // get::@return __breturn: - // [24] stackidx(byte,0) = get::return_p1_x#0 -- _stackidxbyte_vbuc1=vbuxx - txa + // [26] stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return -- _stackidxstruct_4_vbuc1=vssz1 tsx - sta STACK_BASE+0,x - // [25] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 -- _stackidxbyte_vbuc1=vbuz1 - lda.z return_p1_y - tsx - sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x - // [26] stackidx(byte,OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 -- _stackidxbyte_vbuc1=vbuyy - tya - tsx - sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x - // [27] stackidx(byte,OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 -- _stackidxbyte_vbuc1=vbuz1 - lda.z return_p2_y - tsx - sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x - // [28] return + lda.z return + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + lda.z return+1 + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x + lda.z return+2 + sta STACK_BASE+OFFSET_STACK_RETURN_0+2,x + lda.z return+3 + sta STACK_BASE+OFFSET_STACK_RETURN_0+3,x + // [27] return rts } // main main: { - .label v_p2_x = 4 - .label v_p2_y = 5 + .label v = 6 .label i = 2 - // [30] phi from main to main::@1 [phi:main->main::@1] + // [29] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [30] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + // [29] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 sta.z i jmp __b1 // main::@1 __b1: - // [31] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + // [30] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z i cmp #5 bcc __b2 jmp __breturn // main::@return __breturn: - // [32] return + // [31] return rts // main::@2 __b2: - // [33] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + // [32] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 lda.z i pha // sideeffect stackpushbytes(3) -- _stackpushbyte_3 pha pha pha - // [35] callexecute get -- jsr + // [34] callexecute get -- jsr jsr get - // [36] main::v_p1_x#0 = stackpull(byte) -- vbuyy=_stackpullbyte_ + // [35] main::v = stackpull(struct Vector) -- vssz1=_stackpullstruct_4_ pla - tay - // [37] main::v_p1_y#0 = stackpull(byte) -- vbuxx=_stackpullbyte_ + sta.z v pla - tax - // [38] main::v_p2_x#0 = stackpull(byte) -- vbuz1=_stackpullbyte_ + sta.z v+1 pla - sta.z v_p2_x - // [39] main::v_p2_y#0 = stackpull(byte) -- vbuz1=_stackpullbyte_ + sta.z v+2 pla - sta.z v_p2_y - // [40] stackpush(byte) = main::v_p1_x#0 -- _stackpushbyte_=vbuyy - tya + sta.z v+3 + // [36] stackpush(struct Vector) = main::v -- _stackpushstruct_4_=vssz1 + lda.z v+3 pha - // [41] stackpush(byte) = main::v_p1_y#0 -- _stackpushbyte_=vbuxx - txa + lda.z v+2 pha - // [42] stackpush(byte) = main::v_p2_x#0 -- _stackpushbyte_=vbuz1 - lda.z v_p2_x + lda.z v+1 pha - // [43] stackpush(byte) = main::v_p2_y#0 -- _stackpushbyte_=vbuz1 - lda.z v_p2_y + lda.z v pha - // [44] callexecute print -- jsr + // [37] callexecute print -- jsr jsr print // sideeffect stackpullbytes(4) -- _stackpullbyte_4 tsx txa axs #-4 txs - // [46] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + // [39] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 inc.z i - // [30] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [29] phi from main::@2 to main::@1 [phi:main::@2->main::@1] __b1_from___b2: - // [30] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy + // [29] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 } // File Data @@ -804,6 +622,8 @@ Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda.z v+3 +Succesful ASM optimization Pass5UnnecesaryLoadElimination Removing instruction __b1_from___init1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __init1: @@ -820,74 +640,42 @@ FINAL SYMBOL TABLE constant byte OFFSET_STRUCT_POINT_Y = 1 constant byte OFFSET_STRUCT_VECTOR_P2 = 2 constant byte* const SCREEN = (byte*) 1024 +constant byte SIZEOF_STRUCT_VECTOR = 4 constant word STACK_BASE = $103 void __start() __stackcall struct Vector get(byte get::i) +byte~ get::$0 zp[1]:4 500.5 +byte~ get::$1 reg byte x 500.5 +byte~ get::$2 zp[1]:5 500.5 constant byte get::OFFSET_STACK_I = 0 +constant byte get::OFFSET_STACK_RETURN_0 = 0 byte get::i -struct Vector get::return -struct Point get::return_p1 -byte get::return_p1_x -byte get::return_p1_x#0 reg byte x 1251.25 -byte get::return_p1_y -byte get::return_p1_y#0 return_p1_y zp[1]:4 500.5 -struct Point get::return_p2 -byte get::return_p2_x -byte get::return_p2_x#0 reg byte y 500.5 -byte get::return_p2_y -byte get::return_p2_y#0 return_p2_y zp[1]:5 500.5 -struct Point get::v_p1 -byte get::v_p1_x -byte get::v_p1_y -struct Point get::v_p2 -byte get::v_p2_x -byte get::v_p2_y -byte idx loadstore zp[1]:3 441.67647058823525 +byte get::i#0 reg byte y 1251.25 +struct Vector get::return loadstore zp[4]:10 40.04 +struct Vector get::v loadstore zp[4]:14 +byte idx loadstore zp[1]:3 600.68 __stackcall void main() byte main::i byte main::i#1 i zp[1]:2 202.0 -byte main::i#2 i zp[1]:2 26.933333333333334 -struct Vector main::v -struct Point main::v_p1 -byte main::v_p1_x -byte main::v_p1_x#0 reg byte y 50.5 -byte main::v_p1_y -byte main::v_p1_y#0 reg byte x 50.5 -struct Point main::v_p2 -byte main::v_p2_x -byte main::v_p2_x#0 v_p2_x zp[1]:4 50.5 -byte main::v_p2_y -byte main::v_p2_y#0 v_p2_y zp[1]:5 50.5 -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) -constant byte print::OFFSET_STACK_V_P1_X = 3 -constant byte print::OFFSET_STACK_V_P1_Y = 2 -constant byte print::OFFSET_STACK_V_P2_X = 1 -constant byte print::OFFSET_STACK_V_P2_Y = 0 -struct Point print::v_p1 -byte print::v_p1_x -byte print::v_p1_x#0 reg byte y 500.5 -byte print::v_p1_y -byte print::v_p1_y#0 v_p1_y zp[1]:4 400.4 -struct Point print::v_p2 -byte print::v_p2_x -byte print::v_p2_x#0 v_p2_x zp[1]:5 333.6666666666667 -byte print::v_p2_y -byte print::v_p2_y#0 reg byte x 286.0 +byte main::i#2 i zp[1]:2 44.888888888888886 +struct Vector main::v loadstore zp[4]:6 202.0 +__stackcall void print(struct Vector print::v) +constant byte print::OFFSET_STACK_V = 0 +struct Vector print::v loadstore zp[4]:6 143.0 zp[1]:2 [ main::i#2 main::i#1 ] zp[1]:3 [ idx ] -reg byte y [ print::v_p1_x#0 ] -reg byte x [ print::v_p2_y#0 ] -reg byte x [ get::return_p1_x#0 ] -reg byte y [ get::return_p2_x#0 ] -reg byte y [ main::v_p1_x#0 ] -reg byte x [ main::v_p1_y#0 ] -zp[1]:4 [ main::v_p2_x#0 get::return_p1_y#0 print::v_p1_y#0 ] -zp[1]:5 [ main::v_p2_y#0 get::return_p2_y#0 print::v_p2_x#0 ] +reg byte y [ get::i#0 ] +zp[1]:4 [ get::$0 ] +reg byte x [ get::$1 ] +zp[1]:5 [ get::$2 ] +zp[4]:6 [ main::v print::v ] +zp[4]:10 [ get::return ] +zp[4]:14 [ get::v ] FINAL ASSEMBLER -Score: 1247 +Score: 1293 // File Comments // Test a procedure with calling convention stack @@ -902,9 +690,10 @@ Score: 1247 .segment Basic :BasicUpstart(__start) // Global Constants & labels - .const STACK_BASE = $103 .const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const SIZEOF_STRUCT_VECTOR = 4 + .const STACK_BASE = $103 .label SCREEN = $400 .label idx = 3 .segment Code @@ -924,178 +713,177 @@ __start: { rts } // print -// print(byte register(Y) v_p1_x, byte zp(4) v_p1_y, byte zp(5) v_p2_x, byte register(X) v_p2_y) +// print(struct Vector zp(6) v) print: { - .const OFFSET_STACK_V_P1_X = 3 - .const OFFSET_STACK_V_P1_Y = 2 - .const OFFSET_STACK_V_P2_X = 1 - .const OFFSET_STACK_V_P2_Y = 0 - .label v_p1_y = 4 - .label v_p2_x = 5 - // [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) -- vbuyy=_stackidxbyte_vbuc1 + .const OFFSET_STACK_V = 0 + .label v = 6 + // [5] print::v = stackidx(struct Vector,print::OFFSET_STACK_V) -- vssz1=_stackidxstruct_4_vbuc1 tsx - lda STACK_BASE+OFFSET_STACK_V_P1_X,x - tay - // [6] print::v_p1_y#0 = stackidx(byte,print::OFFSET_STACK_V_P1_Y) -- vbuz1=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_V_P1_Y,x - sta.z v_p1_y - // [7] print::v_p2_x#0 = stackidx(byte,print::OFFSET_STACK_V_P2_X) -- vbuz1=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_V_P2_X,x - sta.z v_p2_x - // [8] print::v_p2_y#0 = stackidx(byte,print::OFFSET_STACK_V_P2_Y) -- vbuxx=_stackidxbyte_vbuc1 - tsx - lda STACK_BASE+OFFSET_STACK_V_P2_Y,x - tax + lda STACK_BASE+OFFSET_STACK_V,x + sta.z v + lda STACK_BASE+OFFSET_STACK_V+1,x + sta.z v+1 + lda STACK_BASE+OFFSET_STACK_V+2,x + sta.z v+2 + lda STACK_BASE+OFFSET_STACK_V+3,x + sta.z v+3 // SCREEN[idx++] = v.p1.x - // [9] SCREEN[idx] = print::v_p1_x#0 -- pbuc1_derefidx_vbuz1=vbuyy - tya + // [6] SCREEN[idx] = *((byte*)(struct Point*)&print::v) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda.z v ldy.z idx sta SCREEN,y // SCREEN[idx++] = v.p1.x; - // [10] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [7] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // SCREEN[idx++] = v.p1.y - // [11] SCREEN[idx] = print::v_p1_y#0 -- pbuc1_derefidx_vbuz1=vbuz2 - lda.z v_p1_y + // [8] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_POINT_Y) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda v+OFFSET_STRUCT_POINT_Y ldy.z idx sta SCREEN,y // SCREEN[idx++] = v.p1.y; - // [12] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [9] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // SCREEN[idx++] = v.p2.x - // [13] SCREEN[idx] = print::v_p2_x#0 -- pbuc1_derefidx_vbuz1=vbuz2 - lda.z v_p2_x + // [10] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda v+OFFSET_STRUCT_VECTOR_P2 ldy.z idx sta SCREEN,y // SCREEN[idx++] = v.p2.x; - // [14] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [11] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // SCREEN[idx++] = v.p2.y - // [15] SCREEN[idx] = print::v_p2_y#0 -- pbuc1_derefidx_vbuz1=vbuxx + // [12] SCREEN[idx] = *((byte*)(struct Point*)&print::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) -- pbuc1_derefidx_vbuz1=_deref_pbuc2 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y ldy.z idx - txa sta SCREEN,y // SCREEN[idx++] = v.p2.y; - // [16] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [13] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // SCREEN[idx++] = ' ' - // [17] SCREEN[idx] = ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + // [14] SCREEN[idx] = ' ' -- pbuc1_derefidx_vbuz1=vbuc2 lda #' ' ldy.z idx sta SCREEN,y // SCREEN[idx++] = ' '; - // [18] idx = ++ idx -- vbuz1=_inc_vbuz1 + // [15] idx = ++ idx -- vbuz1=_inc_vbuz1 inc.z idx // print::@return // } - // [19] return + // [16] return rts } // get +// get(byte register(Y) i) get: { .const OFFSET_STACK_I = 0 - .label return_p1_y = 4 - .label return_p2_y = 5 - // [20] get::return_p1_x#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1 + .const OFFSET_STACK_RETURN_0 = 0 + .label return = $a + .label v = $e + .label __0 = 4 + .label __2 = 5 + // [17] get::i#0 = stackidx(byte,get::OFFSET_STACK_I) -- vbuyy=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_I,x - tax - // i/2 - // [21] get::return_p1_y#0 = get::return_p1_x#0 >> 1 -- vbuz1=vbuxx_ror_1 - txa - lsr - sta.z return_p1_y - // i+1 - // [22] get::return_p2_x#0 = get::return_p1_x#0 + 1 -- vbuyy=vbuxx_plus_1 - txa tay - iny + // i/2 + // [18] get::$0 = get::i#0 >> 1 -- vbuz1=vbuyy_ror_1 + tya + lsr + sta.z __0 + // i+1 + // [19] get::$1 = get::i#0 + 1 -- vbuxx=vbuyy_plus_1 + tya + tax + inx // i*2 - // [23] get::return_p2_y#0 = get::return_p1_x#0 << 1 -- vbuz1=vbuxx_rol_1 - txa + // [20] get::$2 = get::i#0 << 1 -- vbuz1=vbuyy_rol_1 + tya asl - sta.z return_p2_y + sta.z __2 + // struct Vector v = { {i, i/2}, {i+1, i*2} } + // [21] *((byte*)(struct Point*)&get::v) = get::i#0 -- _deref_pbuc1=vbuyy + sty.z v + // [22] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_POINT_Y) = get::$0 -- _deref_pbuc1=vbuz1 + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + // [23] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2) = get::$1 -- _deref_pbuc1=vbuxx + stx v+OFFSET_STRUCT_VECTOR_P2 + // [24] *((byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::$2 -- _deref_pbuc1=vbuz1 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // return v; + // [25] *(&get::return) = memcpy(*(&get::v), struct Vector, SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_VECTOR + !: + lda v-1,y + sta return-1,y + dey + bne !- // get::@return // } - // [24] stackidx(byte,0) = get::return_p1_x#0 -- _stackidxbyte_vbuc1=vbuxx - txa + // [26] stackidx(struct Vector,get::OFFSET_STACK_RETURN_0) = get::return -- _stackidxstruct_4_vbuc1=vssz1 tsx - sta STACK_BASE+0,x - // [25] stackidx(byte,OFFSET_STRUCT_POINT_Y) = get::return_p1_y#0 -- _stackidxbyte_vbuc1=vbuz1 - lda.z return_p1_y - tsx - sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x - // [26] stackidx(byte,OFFSET_STRUCT_VECTOR_P2) = get::return_p2_x#0 -- _stackidxbyte_vbuc1=vbuyy - tya - tsx - sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x - // [27] stackidx(byte,OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) = get::return_p2_y#0 -- _stackidxbyte_vbuc1=vbuz1 - lda.z return_p2_y - tsx - sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x - // [28] return + lda.z return + sta STACK_BASE+OFFSET_STACK_RETURN_0,x + lda.z return+1 + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x + lda.z return+2 + sta STACK_BASE+OFFSET_STACK_RETURN_0+2,x + lda.z return+3 + sta STACK_BASE+OFFSET_STACK_RETURN_0+3,x + // [27] return rts } // main main: { - .label v_p2_x = 4 - .label v_p2_y = 5 + .label v = 6 .label i = 2 - // [30] phi from main to main::@1 [phi:main->main::@1] - // [30] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + // [29] phi from main to main::@1 [phi:main->main::@1] + // [29] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 sta.z i // main::@1 __b1: // for(char i=0;i<5;i++) - // [31] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + // [30] if(main::i#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z i cmp #5 bcc __b2 // main::@return // } - // [32] return + // [31] return rts // main::@2 __b2: // struct Vector v = get(i) - // [33] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 + // [32] stackpush(byte) = main::i#2 -- _stackpushbyte_=vbuz1 lda.z i pha // sideeffect stackpushbytes(3) -- _stackpushbyte_3 pha pha pha - // [35] callexecute get -- jsr + // [34] callexecute get -- jsr jsr get - // [36] main::v_p1_x#0 = stackpull(byte) -- vbuyy=_stackpullbyte_ + // [35] main::v = stackpull(struct Vector) -- vssz1=_stackpullstruct_4_ pla - tay - // [37] main::v_p1_y#0 = stackpull(byte) -- vbuxx=_stackpullbyte_ + sta.z v pla - tax - // [38] main::v_p2_x#0 = stackpull(byte) -- vbuz1=_stackpullbyte_ + sta.z v+1 pla - sta.z v_p2_x - // [39] main::v_p2_y#0 = stackpull(byte) -- vbuz1=_stackpullbyte_ + sta.z v+2 pla - sta.z v_p2_y + sta.z v+3 // print(v) - // [40] stackpush(byte) = main::v_p1_x#0 -- _stackpushbyte_=vbuyy - tya + // [36] stackpush(struct Vector) = main::v -- _stackpushstruct_4_=vssz1 pha - // [41] stackpush(byte) = main::v_p1_y#0 -- _stackpushbyte_=vbuxx - txa + lda.z v+2 pha - // [42] stackpush(byte) = main::v_p2_x#0 -- _stackpushbyte_=vbuz1 - lda.z v_p2_x + lda.z v+1 pha - // [43] stackpush(byte) = main::v_p2_y#0 -- _stackpushbyte_=vbuz1 - lda.z v_p2_y + lda.z v pha - // [44] callexecute print -- jsr + // [37] callexecute print -- jsr jsr print // sideeffect stackpullbytes(4) -- _stackpullbyte_4 tsx @@ -1103,10 +891,10 @@ main: { axs #-4 txs // for(char i=0;i<5;i++) - // [46] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 + // [39] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1 inc.z i - // [30] phi from main::@2 to main::@1 [phi:main::@2->main::@1] - // [30] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy + // [29] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + // [29] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy jmp __b1 } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-11.sym b/src/test/ref/procedure-callingconvention-stack-11.sym index 11a8eec43..0225f00b7 100644 --- a/src/test/ref/procedure-callingconvention-stack-11.sym +++ b/src/test/ref/procedure-callingconvention-stack-11.sym @@ -1,67 +1,35 @@ constant byte OFFSET_STRUCT_POINT_Y = 1 constant byte OFFSET_STRUCT_VECTOR_P2 = 2 constant byte* const SCREEN = (byte*) 1024 +constant byte SIZEOF_STRUCT_VECTOR = 4 constant word STACK_BASE = $103 void __start() __stackcall struct Vector get(byte get::i) +byte~ get::$0 zp[1]:4 500.5 +byte~ get::$1 reg byte x 500.5 +byte~ get::$2 zp[1]:5 500.5 constant byte get::OFFSET_STACK_I = 0 +constant byte get::OFFSET_STACK_RETURN_0 = 0 byte get::i -struct Vector get::return -struct Point get::return_p1 -byte get::return_p1_x -byte get::return_p1_x#0 reg byte x 1251.25 -byte get::return_p1_y -byte get::return_p1_y#0 return_p1_y zp[1]:4 500.5 -struct Point get::return_p2 -byte get::return_p2_x -byte get::return_p2_x#0 reg byte y 500.5 -byte get::return_p2_y -byte get::return_p2_y#0 return_p2_y zp[1]:5 500.5 -struct Point get::v_p1 -byte get::v_p1_x -byte get::v_p1_y -struct Point get::v_p2 -byte get::v_p2_x -byte get::v_p2_y -byte idx loadstore zp[1]:3 441.67647058823525 +byte get::i#0 reg byte y 1251.25 +struct Vector get::return loadstore zp[4]:10 40.04 +struct Vector get::v loadstore zp[4]:14 +byte idx loadstore zp[1]:3 600.68 __stackcall void main() byte main::i byte main::i#1 i zp[1]:2 202.0 -byte main::i#2 i zp[1]:2 26.933333333333334 -struct Vector main::v -struct Point main::v_p1 -byte main::v_p1_x -byte main::v_p1_x#0 reg byte y 50.5 -byte main::v_p1_y -byte main::v_p1_y#0 reg byte x 50.5 -struct Point main::v_p2 -byte main::v_p2_x -byte main::v_p2_x#0 v_p2_x zp[1]:4 50.5 -byte main::v_p2_y -byte main::v_p2_y#0 v_p2_y zp[1]:5 50.5 -__stackcall void print(byte print::v_p1_x , byte print::v_p1_y , byte print::v_p2_x , byte print::v_p2_y) -constant byte print::OFFSET_STACK_V_P1_X = 3 -constant byte print::OFFSET_STACK_V_P1_Y = 2 -constant byte print::OFFSET_STACK_V_P2_X = 1 -constant byte print::OFFSET_STACK_V_P2_Y = 0 -struct Point print::v_p1 -byte print::v_p1_x -byte print::v_p1_x#0 reg byte y 500.5 -byte print::v_p1_y -byte print::v_p1_y#0 v_p1_y zp[1]:4 400.4 -struct Point print::v_p2 -byte print::v_p2_x -byte print::v_p2_x#0 v_p2_x zp[1]:5 333.6666666666667 -byte print::v_p2_y -byte print::v_p2_y#0 reg byte x 286.0 +byte main::i#2 i zp[1]:2 44.888888888888886 +struct Vector main::v loadstore zp[4]:6 202.0 +__stackcall void print(struct Vector print::v) +constant byte print::OFFSET_STACK_V = 0 +struct Vector print::v loadstore zp[4]:6 143.0 zp[1]:2 [ main::i#2 main::i#1 ] zp[1]:3 [ idx ] -reg byte y [ print::v_p1_x#0 ] -reg byte x [ print::v_p2_y#0 ] -reg byte x [ get::return_p1_x#0 ] -reg byte y [ get::return_p2_x#0 ] -reg byte y [ main::v_p1_x#0 ] -reg byte x [ main::v_p1_y#0 ] -zp[1]:4 [ main::v_p2_x#0 get::return_p1_y#0 print::v_p1_y#0 ] -zp[1]:5 [ main::v_p2_y#0 get::return_p2_y#0 print::v_p2_x#0 ] +reg byte y [ get::i#0 ] +zp[1]:4 [ get::$0 ] +reg byte x [ get::$1 ] +zp[1]:5 [ get::$2 ] +zp[4]:6 [ main::v print::v ] +zp[4]:10 [ get::return ] +zp[4]:14 [ get::v ] diff --git a/src/test/ref/procedure-callingconvention-stack-13.asm b/src/test/ref/procedure-callingconvention-stack-13.asm index ad0c27a9a..3fd469d58 100644 --- a/src/test/ref/procedure-callingconvention-stack-13.asm +++ b/src/test/ref/procedure-callingconvention-stack-13.asm @@ -14,7 +14,7 @@ // pow2(byte register(A) n) pow2: { .const OFFSET_STACK_N = 0 - .const OFFSET_STACK_RETURN = 0 + .const OFFSET_STACK_RETURN_0 = 0 tsx lda STACK_BASE+OFFSET_STACK_N,x // if (n == 0) @@ -35,7 +35,7 @@ pow2: { __breturn: // } tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_0,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-13.cfg b/src/test/ref/procedure-callingconvention-stack-13.cfg index f22a8875b..afe07b189 100644 --- a/src/test/ref/procedure-callingconvention-stack-13.cfg +++ b/src/test/ref/procedure-callingconvention-stack-13.cfg @@ -13,7 +13,7 @@ pow2::@1: scope:[pow2] from pow2 to:pow2::@return pow2::@return: scope:[pow2] from pow2 pow2::@1 [7] pow2::return#2 = phi( pow2/1, pow2::@1/pow2::return#1 ) - [8] stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return#2 + [8] stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return#2 [9] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-13.log b/src/test/ref/procedure-callingconvention-stack-13.log index 1e5fabe8d..08a367fc9 100644 --- a/src/test/ref/procedure-callingconvention-stack-13.log +++ b/src/test/ref/procedure-callingconvention-stack-13.log @@ -3,7 +3,7 @@ Eliminating unused variable with no statement pow2::$2 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call pow2 6 Calling convention __stackcall adding prepare/execute/finalize for pow2::c = call pow2 pow2::$1 Calling convention STACK_CALL replacing param(pow2::n) with stackidx(byte,pow2::OFFSET_STACK_N) -Calling convention STACK_CALL adding stack return stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return +Calling convention STACK_CALL adding stack return stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(byte) Calling convention STACK_CALL adding stack pull pow2::c = stackpull(byte) Calling convention STACK_CALL adding stack push stackpush(byte) = 6 @@ -42,7 +42,7 @@ pow2::@2: scope:[pow2] from pow2 to:pow2::@return pow2::@return: scope:[pow2] from pow2::@1 pow2::@2 pow2::return#2 = phi( pow2::@1/pow2::return#0, pow2::@2/pow2::return#1 ) - stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return#2 + stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return#2 return to:@return @@ -67,7 +67,7 @@ bool~ pow2::$0 number~ pow2::$1 byte~ pow2::$3 constant byte pow2::OFFSET_STACK_N = 0 -constant byte pow2::OFFSET_STACK_RETURN = 0 +constant byte pow2::OFFSET_STACK_RETURN_0 = 0 byte pow2::c byte pow2::c#0 byte pow2::n @@ -141,7 +141,7 @@ pow2::@1: scope:[pow2] from pow2 to:pow2::@return pow2::@return: scope:[pow2] from pow2 pow2::@1 [7] pow2::return#2 = phi( pow2/1, pow2::@1/pow2::return#1 ) - [8] stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return#2 + [8] stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return#2 [9] return to:@return @@ -191,7 +191,7 @@ REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] pow2::n#0 = stackidx(byte,pow2::OFFSET_STACK_N) [ pow2::n#0 ] ( pow2:11 [ pow2::n#0 ] { } ) always clobbers reg byte a reg byte x Statement [5] pow2::c#0 = stackpull(byte) [ pow2::c#0 ] ( pow2:11 [ pow2::c#0 ] { } ) always clobbers reg byte a Statement [6] pow2::return#1 = pow2::c#0 + pow2::c#0 [ pow2::return#1 ] ( pow2:11 [ pow2::return#1 ] { } ) always clobbers reg byte a -Statement [8] stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return#2 [ ] ( pow2:11 [ ] { } ) always clobbers reg byte x +Statement [8] stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return#2 [ ] ( pow2:11 [ ] { } ) always clobbers reg byte x Statement [10] stackpush(byte) = 6 [ ] ( [ ] { } ) always clobbers reg byte a Statement [12] main::$0 = stackpull(byte) [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a Potential registers zp[1]:2 [ pow2::return#2 pow2::return#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , @@ -231,7 +231,7 @@ ASSEMBLER BEFORE OPTIMIZATION // pow2(byte register(A) n) pow2: { .const OFFSET_STACK_N = 0 - .const OFFSET_STACK_RETURN = 0 + .const OFFSET_STACK_RETURN_0 = 0 // [0] pow2::n#0 = stackidx(byte,pow2::OFFSET_STACK_N) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_N,x @@ -263,9 +263,9 @@ pow2: { jmp __breturn // pow2::@return __breturn: - // [8] stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return#2 -- _stackidxbyte_vbuc1=vbuaa + // [8] stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return#2 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_0,x // [9] return rts } @@ -308,7 +308,7 @@ byte~ main::$0 reg byte a 4.0 __stackcall byte pow2(byte pow2::n) byte~ pow2::$1 reg byte a 22.0 constant byte pow2::OFFSET_STACK_N = 0 -constant byte pow2::OFFSET_STACK_RETURN = 0 +constant byte pow2::OFFSET_STACK_RETURN_0 = 0 byte pow2::c byte pow2::c#0 reg byte a 33.0 byte pow2::n @@ -347,7 +347,7 @@ Score: 72 // pow2(byte register(A) n) pow2: { .const OFFSET_STACK_N = 0 - .const OFFSET_STACK_RETURN = 0 + .const OFFSET_STACK_RETURN_0 = 0 // [0] pow2::n#0 = stackidx(byte,pow2::OFFSET_STACK_N) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_N,x @@ -380,9 +380,9 @@ pow2: { // pow2::@return __breturn: // } - // [8] stackidx(byte,pow2::OFFSET_STACK_RETURN) = pow2::return#2 -- _stackidxbyte_vbuc1=vbuaa + // [8] stackidx(byte,pow2::OFFSET_STACK_RETURN_0) = pow2::return#2 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_0,x // [9] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-13.sym b/src/test/ref/procedure-callingconvention-stack-13.sym index 5e2e34558..9f668a555 100644 --- a/src/test/ref/procedure-callingconvention-stack-13.sym +++ b/src/test/ref/procedure-callingconvention-stack-13.sym @@ -5,7 +5,7 @@ byte~ main::$0 reg byte a 4.0 __stackcall byte pow2(byte pow2::n) byte~ pow2::$1 reg byte a 22.0 constant byte pow2::OFFSET_STACK_N = 0 -constant byte pow2::OFFSET_STACK_RETURN = 0 +constant byte pow2::OFFSET_STACK_RETURN_0 = 0 byte pow2::c byte pow2::c#0 reg byte a 33.0 byte pow2::n diff --git a/src/test/ref/procedure-callingconvention-stack-2.asm b/src/test/ref/procedure-callingconvention-stack-2.asm index 5571ea765..02333838c 100644 --- a/src/test/ref/procedure-callingconvention-stack-2.asm +++ b/src/test/ref/procedure-callingconvention-stack-2.asm @@ -14,7 +14,7 @@ plus: { .const OFFSET_STACK_A = 2 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 2 + .const OFFSET_STACK_RETURN_2 = 2 .label a = 4 .label b = 2 .label return = 4 @@ -39,9 +39,9 @@ plus: { // } tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_2,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-2.cfg b/src/test/ref/procedure-callingconvention-stack-2.cfg index c9c512e30..1f09d58d4 100644 --- a/src/test/ref/procedure-callingconvention-stack-2.cfg +++ b/src/test/ref/procedure-callingconvention-stack-2.cfg @@ -6,7 +6,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [4] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-2.log b/src/test/ref/procedure-callingconvention-stack-2.log index 98a2f0ca9..eaa8f6f93 100644 --- a/src/test/ref/procedure-callingconvention-stack-2.log +++ b/src/test/ref/procedure-callingconvention-stack-2.log @@ -3,7 +3,7 @@ Adding parameter assignment in __stackcall procedure plus::a = param(plus::a) Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus $1234 $2345 Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B) -Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return +Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(word) Calling convention STACK_CALL adding stack push stackpush(word) = $1234 Calling convention STACK_CALL adding stack push stackpush(word) = $2345 @@ -33,7 +33,7 @@ plus: scope:[plus] from to:plus::@return plus::@return: scope:[plus] from plus plus::return#1 = phi( plus/plus::return#0 ) - stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#1 + stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#1 return to:@return @@ -59,7 +59,7 @@ __stackcall word plus(word plus::a , word plus::b) word~ plus::$0 constant byte plus::OFFSET_STACK_A = 2 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 2 +constant byte plus::OFFSET_STACK_RETURN_2 = 2 word plus::a word plus::a#0 word plus::b @@ -121,7 +121,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [4] return to:@return @@ -168,7 +168,7 @@ REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] plus::a#0 = stackidx(word,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x Statement [1] plus::b#0 = stackidx(word,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a -Statement [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte a reg byte x +Statement [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte a reg byte x Statement [5] stackpush(word) = $1234 [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] stackpush(word) = $2345 [ ] ( [ ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(2) always clobbers reg byte a @@ -213,7 +213,7 @@ ASSEMBLER BEFORE OPTIMIZATION plus: { .const OFFSET_STACK_A = 2 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 2 + .const OFFSET_STACK_RETURN_2 = 2 .label a = 4 .label b = 2 .label return = 4 @@ -240,12 +240,12 @@ plus: { jmp __breturn // plus::@return __breturn: - // [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_2,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x // [4] return rts } @@ -301,7 +301,7 @@ word~ main::$0 zp[2]:4 4.0 __stackcall word plus(word plus::a , word plus::b) constant byte plus::OFFSET_STACK_A = 2 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 2 +constant byte plus::OFFSET_STACK_RETURN_2 = 2 word plus::a word plus::a#0 a zp[2]:4 11.0 word plus::b @@ -336,7 +336,7 @@ Score: 146 plus: { .const OFFSET_STACK_A = 2 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 2 + .const OFFSET_STACK_RETURN_2 = 2 .label a = 4 .label b = 2 .label return = 4 @@ -363,12 +363,12 @@ plus: { sta.z return+1 // plus::@return // } - // [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_2,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x // [4] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-2.sym b/src/test/ref/procedure-callingconvention-stack-2.sym index 6ce921833..266a44da6 100644 --- a/src/test/ref/procedure-callingconvention-stack-2.sym +++ b/src/test/ref/procedure-callingconvention-stack-2.sym @@ -5,7 +5,7 @@ word~ main::$0 zp[2]:4 4.0 __stackcall word plus(word plus::a , word plus::b) constant byte plus::OFFSET_STACK_A = 2 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 2 +constant byte plus::OFFSET_STACK_RETURN_2 = 2 word plus::a word plus::a#0 a zp[2]:4 11.0 word plus::b diff --git a/src/test/ref/procedure-callingconvention-stack-3.asm b/src/test/ref/procedure-callingconvention-stack-3.asm index 39408d932..13b77bda0 100644 --- a/src/test/ref/procedure-callingconvention-stack-3.asm +++ b/src/test/ref/procedure-callingconvention-stack-3.asm @@ -17,7 +17,7 @@ plus: { .const OFFSET_STACK_A = 2 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 2 + .const OFFSET_STACK_RETURN_2 = 2 .label a = 4 .label b = 2 .label return = 4 @@ -42,9 +42,9 @@ plus: { // } tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_2,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-3.cfg b/src/test/ref/procedure-callingconvention-stack-3.cfg index a27f8624d..281f6718a 100644 --- a/src/test/ref/procedure-callingconvention-stack-3.cfg +++ b/src/test/ref/procedure-callingconvention-stack-3.cfg @@ -6,7 +6,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [4] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-3.log b/src/test/ref/procedure-callingconvention-stack-3.log index a20c17818..df0c91b30 100644 --- a/src/test/ref/procedure-callingconvention-stack-3.log +++ b/src/test/ref/procedure-callingconvention-stack-3.log @@ -3,7 +3,7 @@ Adding parameter assignment in __stackcall procedure plus::a = param(plus::a) Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7 Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B) -Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return +Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(word) Calling convention STACK_CALL adding stack push stackpush(word) = '0' Calling convention STACK_CALL adding stack push stackpush(word) = 7 @@ -33,7 +33,7 @@ plus: scope:[plus] from to:plus::@return plus::@return: scope:[plus] from plus plus::return#1 = phi( plus/plus::return#0 ) - stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#1 + stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#1 return to:@return @@ -59,7 +59,7 @@ __stackcall word plus(word plus::a , word plus::b) word~ plus::$0 constant byte plus::OFFSET_STACK_A = 2 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 2 +constant byte plus::OFFSET_STACK_RETURN_2 = 2 word plus::a word plus::a#0 word plus::b @@ -117,7 +117,7 @@ plus: scope:[plus] from [2] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 + [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [4] return to:@return @@ -164,7 +164,7 @@ REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] plus::a#0 = stackidx(word,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x Statement [1] plus::b#0 = stackidx(word,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a -Statement [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte a reg byte x +Statement [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte a reg byte x Statement [5] stackpush(word) = '0' [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] stackpush(word) = 7 [ ] ( [ ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(2) always clobbers reg byte a @@ -212,7 +212,7 @@ ASSEMBLER BEFORE OPTIMIZATION plus: { .const OFFSET_STACK_A = 2 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 2 + .const OFFSET_STACK_RETURN_2 = 2 .label a = 4 .label b = 2 .label return = 4 @@ -239,12 +239,12 @@ plus: { jmp __breturn // plus::@return __breturn: - // [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_2,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x // [4] return rts } @@ -300,7 +300,7 @@ word~ main::$0 zp[2]:4 4.0 __stackcall word plus(word plus::a , word plus::b) constant byte plus::OFFSET_STACK_A = 2 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 2 +constant byte plus::OFFSET_STACK_RETURN_2 = 2 word plus::a word plus::a#0 a zp[2]:4 11.0 word plus::b @@ -338,7 +338,7 @@ Score: 146 plus: { .const OFFSET_STACK_A = 2 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 2 + .const OFFSET_STACK_RETURN_2 = 2 .label a = 4 .label b = 2 .label return = 4 @@ -365,12 +365,12 @@ plus: { sta.z return+1 // plus::@return // } - // [3] stackidx(word,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [3] stackidx(word,plus::OFFSET_STACK_RETURN_2) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_2,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x // [4] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-3.sym b/src/test/ref/procedure-callingconvention-stack-3.sym index 6ce921833..266a44da6 100644 --- a/src/test/ref/procedure-callingconvention-stack-3.sym +++ b/src/test/ref/procedure-callingconvention-stack-3.sym @@ -5,7 +5,7 @@ word~ main::$0 zp[2]:4 4.0 __stackcall word plus(word plus::a , word plus::b) constant byte plus::OFFSET_STACK_A = 2 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 2 +constant byte plus::OFFSET_STACK_RETURN_2 = 2 word plus::a word plus::a#0 a zp[2]:4 11.0 word plus::b diff --git a/src/test/ref/procedure-callingconvention-stack-4.asm b/src/test/ref/procedure-callingconvention-stack-4.asm index 914ea103b..39728b9a8 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.asm +++ b/src/test/ref/procedure-callingconvention-stack-4.asm @@ -23,7 +23,7 @@ __start: { plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 4 tsx lda STACK_BASE+OFFSET_STACK_A,x @@ -37,7 +37,7 @@ plus: { adc.z a // } tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-4.cfg b/src/test/ref/procedure-callingconvention-stack-4.cfg index 1520eb53f..720a4740b 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.cfg +++ b/src/test/ref/procedure-callingconvention-stack-4.cfg @@ -22,7 +22,7 @@ plus: scope:[plus] from [8] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [9] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 + [9] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [10] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-4.log b/src/test/ref/procedure-callingconvention-stack-4.log index 6e40c78a3..8ed8e7f1c 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.log +++ b/src/test/ref/procedure-callingconvention-stack-4.log @@ -7,7 +7,7 @@ Eliminating unused variable with no statement main::$1 Calling convention __stackcall adding prepare/execute/finalize for main::w = call plus '0' main::v Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B) -Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return +Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return Calling convention STACK_CALL adding stack pull main::w = stackpull(byte) Calling convention STACK_CALL adding stack push stackpush(byte) = '0' Calling convention STACK_CALL adding stack push stackpush(byte) = main::v @@ -46,7 +46,7 @@ plus: scope:[plus] from to:plus::@return plus::@return: scope:[plus] from plus plus::return#1 = phi( plus/plus::return#0 ) - stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#1 + stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#1 return to:@return @@ -85,7 +85,7 @@ __stackcall byte plus(byte plus::a , byte plus::b) byte~ plus::$0 constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 byte plus::b @@ -163,7 +163,7 @@ plus: scope:[plus] from [8] plus::return#0 = plus::a#0 + plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [9] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 + [9] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [10] return to:@return @@ -245,7 +245,7 @@ Statement [6] plus::b#0 = stackidx(byte,plus::OFFSET_STACK_B) [ i plus::a#0 plus Removing always clobbered register reg byte a as potential for zp[1]:4 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:4 [ plus::a#0 ] Statement [8] plus::return#0 = plus::a#0 + plus::b#0 [ i plus::return#0 ] ( main:3::plus:16 [ main::a#2 i plus::return#0 ] { } ) always clobbers reg byte a -Statement [9] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 [ i ] ( main:3::plus:16 [ main::a#2 i ] { } ) always clobbers reg byte x +Statement [9] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ i ] ( main:3::plus:16 [ main::a#2 i ] { } ) always clobbers reg byte x Statement [14] stackpush(byte) = '0' [ i main::a#2 main::v#0 ] ( main:3 [ i main::a#2 main::v#0 ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:7 [ main::v#0 ] Statement [15] stackpush(byte) = main::v#0 [ i main::a#2 ] ( main:3 [ i main::a#2 ] { } ) always clobbers reg byte a @@ -259,7 +259,7 @@ Statement [1] i = 0 [ i ] ( [ i ] { } ) always clobbers reg byte a Statement [5] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) [ i plus::a#0 ] ( main:3::plus:16 [ main::a#2 i plus::a#0 ] { } ) always clobbers reg byte a reg byte x Statement [6] plus::b#0 = stackidx(byte,plus::OFFSET_STACK_B) [ i plus::a#0 plus::b#0 ] ( main:3::plus:16 [ main::a#2 i plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x Statement [8] plus::return#0 = plus::a#0 + plus::b#0 [ i plus::return#0 ] ( main:3::plus:16 [ main::a#2 i plus::return#0 ] { } ) always clobbers reg byte a -Statement [9] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 [ i ] ( main:3::plus:16 [ main::a#2 i ] { } ) always clobbers reg byte x +Statement [9] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ i ] ( main:3::plus:16 [ main::a#2 i ] { } ) always clobbers reg byte x Statement [14] stackpush(byte) = '0' [ i main::a#2 main::v#0 ] ( main:3 [ i main::a#2 main::v#0 ] { } ) always clobbers reg byte a Statement [15] stackpush(byte) = main::v#0 [ i main::a#2 ] ( main:3 [ i main::a#2 ] { } ) always clobbers reg byte a Statement sideeffect stackpullbytes(1) always clobbers reg byte a @@ -339,7 +339,7 @@ __start: { plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 4 // [5] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -356,9 +356,9 @@ plus: { jmp __breturn // plus::@return __breturn: - // [9] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [9] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [10] return rts } @@ -452,7 +452,7 @@ byte main::w#0 reg byte a 202.0 __stackcall byte plus(byte plus::a , byte plus::b) constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 a zp[1]:4 667.3333333333334 byte plus::b @@ -511,7 +511,7 @@ __start: { plus: { .const OFFSET_STACK_A = 1 .const OFFSET_STACK_B = 0 - .const OFFSET_STACK_RETURN = 1 + .const OFFSET_STACK_RETURN_1 = 1 .label a = 4 // [5] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx @@ -529,9 +529,9 @@ plus: { adc.z a // plus::@return // } - // [9] stackidx(byte,plus::OFFSET_STACK_RETURN) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [9] stackidx(byte,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_1,x // [10] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-4.sym b/src/test/ref/procedure-callingconvention-stack-4.sym index db9fcde94..f133e09d8 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.sym +++ b/src/test/ref/procedure-callingconvention-stack-4.sym @@ -14,7 +14,7 @@ byte main::w#0 reg byte a 202.0 __stackcall byte plus(byte plus::a , byte plus::b) constant byte plus::OFFSET_STACK_A = 1 constant byte plus::OFFSET_STACK_B = 0 -constant byte plus::OFFSET_STACK_RETURN = 1 +constant byte plus::OFFSET_STACK_RETURN_1 = 1 byte plus::a byte plus::a#0 a zp[1]:4 667.3333333333334 byte plus::b diff --git a/src/test/ref/procedure-callingconvention-stack-5.asm b/src/test/ref/procedure-callingconvention-stack-5.asm index 7d56df05d..6161a5d75 100644 --- a/src/test/ref/procedure-callingconvention-stack-5.asm +++ b/src/test/ref/procedure-callingconvention-stack-5.asm @@ -23,7 +23,7 @@ __start: { rts } next: { - .const OFFSET_STACK_RETURN = 0 + .const OFFSET_STACK_RETURN_0 = 0 .label return = 2 // return current++; lda.z current @@ -37,9 +37,9 @@ next: { // } tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_0,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x rts } main: { diff --git a/src/test/ref/procedure-callingconvention-stack-5.cfg b/src/test/ref/procedure-callingconvention-stack-5.cfg index 1053a1eb3..45450ec17 100644 --- a/src/test/ref/procedure-callingconvention-stack-5.cfg +++ b/src/test/ref/procedure-callingconvention-stack-5.cfg @@ -20,7 +20,7 @@ next: scope:[next] from [6] current = ++ current to:next::@return next::@return: scope:[next] from next - [7] stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return#0 + [7] stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return#0 [8] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-5.log b/src/test/ref/procedure-callingconvention-stack-5.log index 2c23e9038..aafd9dae7 100644 --- a/src/test/ref/procedure-callingconvention-stack-5.log +++ b/src/test/ref/procedure-callingconvention-stack-5.log @@ -2,7 +2,7 @@ Converting variable modified inside __stackcall procedure next() to load/store c Inlined call call __init Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call next Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call next -Calling convention STACK_CALL adding stack return stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return +Calling convention STACK_CALL adding stack return stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return Calling convention STACK_CALL adding stack pull main::$0 = stackpull(signed word) Calling convention STACK_CALL adding stack pull main::$1 = stackpull(signed word) @@ -32,7 +32,7 @@ next: scope:[next] from to:next::@return next::@return: scope:[next] from next next::return#1 = phi( next/next::return#0 ) - stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return#1 + stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return#1 return to:@return @@ -63,7 +63,7 @@ signed word~ main::$1 number~ main::$2 number~ main::$3 __stackcall signed word next() -constant byte next::OFFSET_STACK_RETURN = 0 +constant byte next::OFFSET_STACK_RETURN_0 = 0 signed word next::return signed word next::return#0 signed word next::return#1 @@ -139,7 +139,7 @@ next: scope:[next] from [6] current = ++ current to:next::@return next::@return: scope:[next] from next - [7] stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return#0 + [7] stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return#0 [8] return to:@return @@ -186,7 +186,7 @@ Allocated zp[2]:8 [ main::$1 ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [1] current = $30 [ current ] ( [ current ] { } ) always clobbers reg byte a Statement [5] next::return#0 = current [ current next::return#0 ] ( main:3::next:10 [ current next::return#0 ] { } main:3::next:14 [ current next::return#0 ] { } ) always clobbers reg byte a -Statement [7] stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return#0 [ current ] ( main:3::next:10 [ current ] { } main:3::next:14 [ current ] { } ) always clobbers reg byte a reg byte x +Statement [7] stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return#0 [ current ] ( main:3::next:10 [ current ] { } main:3::next:14 [ current ] { } ) always clobbers reg byte a reg byte x Statement [11] main::$0 = stackpull(signed word) [ current main::$0 ] ( main:3 [ current main::$0 ] { } ) always clobbers reg byte a Statement [12] *SCREEN = main::$0 [ current ] ( main:3 [ current ] { } ) always clobbers reg byte a Statement [15] main::$1 = stackpull(signed word) [ main::$1 ] ( main:3 [ main::$1 ] { } ) always clobbers reg byte a @@ -255,7 +255,7 @@ __start: { } // next next: { - .const OFFSET_STACK_RETURN = 0 + .const OFFSET_STACK_RETURN_0 = 0 .label return = 2 // [5] next::return#0 = current -- vwsz1=vwsz2 lda.z current @@ -270,12 +270,12 @@ next: { jmp __breturn // next::@return __breturn: - // [7] stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return#0 -- _stackidxsword_vbuc1=vwsz1 + // [7] stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return#0 -- _stackidxsword_vbuc1=vwsz1 tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_0,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x // [8] return rts } @@ -347,7 +347,7 @@ void main() signed word~ main::$0 zp[2]:2 22.0 signed word~ main::$1 zp[2]:4 22.0 __stackcall signed word next() -constant byte next::OFFSET_STACK_RETURN = 0 +constant byte next::OFFSET_STACK_RETURN_0 = 0 signed word next::return signed word next::return#0 return zp[2]:2 101.0 @@ -395,7 +395,7 @@ __start: { } // next next: { - .const OFFSET_STACK_RETURN = 0 + .const OFFSET_STACK_RETURN_0 = 0 .label return = 2 // return current++; // [5] next::return#0 = current -- vwsz1=vwsz2 @@ -410,12 +410,12 @@ next: { !: // next::@return // } - // [7] stackidx(signed word,next::OFFSET_STACK_RETURN) = next::return#0 -- _stackidxsword_vbuc1=vwsz1 + // [7] stackidx(signed word,next::OFFSET_STACK_RETURN_0) = next::return#0 -- _stackidxsword_vbuc1=vwsz1 tsx lda.z return - sta STACK_BASE+OFFSET_STACK_RETURN,x + sta STACK_BASE+OFFSET_STACK_RETURN_0,x lda.z return+1 - sta STACK_BASE+OFFSET_STACK_RETURN+1,x + sta STACK_BASE+OFFSET_STACK_RETURN_0+1,x // [8] return rts } diff --git a/src/test/ref/procedure-callingconvention-stack-5.sym b/src/test/ref/procedure-callingconvention-stack-5.sym index 99ea184f2..8fdea7113 100644 --- a/src/test/ref/procedure-callingconvention-stack-5.sym +++ b/src/test/ref/procedure-callingconvention-stack-5.sym @@ -7,7 +7,7 @@ void main() signed word~ main::$0 zp[2]:2 22.0 signed word~ main::$1 zp[2]:4 22.0 __stackcall signed word next() -constant byte next::OFFSET_STACK_RETURN = 0 +constant byte next::OFFSET_STACK_RETURN_0 = 0 signed word next::return signed word next::return#0 return zp[2]:2 101.0 diff --git a/src/test/ref/procedure-declare-8.cfg b/src/test/ref/procedure-declare-8.cfg index 9bc2b77f6..a671cddcc 100644 --- a/src/test/ref/procedure-declare-8.cfg +++ b/src/test/ref/procedure-declare-8.cfg @@ -2,8 +2,8 @@ void main() main: scope:[main] from [0] phi() - [1] call proc1 - [2] call proc2 + [1] callexecute proc1 + [2] callexecute proc2 to:main::@return main::@return: scope:[main] from main [3] return diff --git a/src/test/ref/procedure-declare-8.log b/src/test/ref/procedure-declare-8.log index 3f1736855..88780dcba 100644 --- a/src/test/ref/procedure-declare-8.log +++ b/src/test/ref/procedure-declare-8.log @@ -1,4 +1,6 @@ Inlined call call __init +Calling convention STACK_CALL adding prepare/execute/finalize for call *proc_ptr +Calling convention STACK_CALL adding prepare/execute/finalize for call *proc_ptr CONTROL FLOW GRAPH SSA @@ -21,9 +23,9 @@ proc2::@return: scope:[proc2] from proc2 void main() main: scope:[main] from __start::@1 proc_ptr#0 = &proc1 - call *proc_ptr#0 + callexecute *proc_ptr#0 proc_ptr#1 = &proc2 - call *proc_ptr#1 + callexecute *proc_ptr#1 to:main::@return main::@return: scope:[main] from main proc_ptr#6 = phi( main/proc_ptr#1 ) @@ -89,8 +91,8 @@ Constant proc_ptr#0 = &proc1 Constant proc_ptr#1 = &proc2 Constant proc_ptr#3 = (void()*) 0 Successful SSA optimization Pass2ConstantIdentification -Replacing constant pointer function [5] call proc1 -Replacing constant pointer function [7] call proc2 +Replacing constant pointer function [5] callexecute proc1 +Replacing constant pointer function [7] callexecute proc2 Successful SSA optimization Pass2ConstantCallPointerIdentification Simplifying expression containing zero SCREEN in [0] SCREEN[0] = 'a' Successful SSA optimization PassNSimplifyExpressionWithZero @@ -120,8 +122,8 @@ FINAL CONTROL FLOW GRAPH void main() main: scope:[main] from [0] phi() - [1] call proc1 - [2] call proc2 + [1] callexecute proc1 + [2] callexecute proc2 to:main::@return main::@return: scope:[main] from main [3] return @@ -184,9 +186,9 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Code // main main: { - // [1] call proc1 + // [1] callexecute proc1 -- jsr jsr proc1 - // [2] call proc2 + // [2] callexecute proc2 -- jsr jsr proc2 jmp __breturn // main::@return @@ -257,9 +259,9 @@ Score: 42 // main main: { // (*proc_ptr)() - // [1] call proc1 + // [1] callexecute proc1 -- jsr jsr proc1 - // [2] call proc2 + // [2] callexecute proc2 -- jsr jsr proc2 // main::@return // } diff --git a/src/test/ref/type-truncate.asm b/src/test/ref/type-truncate.asm new file mode 100644 index 000000000..37ded8e01 --- /dev/null +++ b/src/test/ref/type-truncate.asm @@ -0,0 +1,20 @@ +// Type match bytes can be assigned from integers without issue + // Commodore 64 PRG executable file +.file [name="type-truncate.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) +.segment Code +main: { + .const w = $1388 + .const b = $ff&w + .label screen = $400 + // screen[0] = b + lda #b + sta screen + // } + rts +} diff --git a/src/test/ref/type-truncate.cfg b/src/test/ref/type-truncate.cfg new file mode 100644 index 000000000..3615af48c --- /dev/null +++ b/src/test/ref/type-truncate.cfg @@ -0,0 +1,8 @@ + +void main() +main: scope:[main] from + [0] *main::screen = main::b#0 + to:main::@return +main::@return: scope:[main] from main + [1] return + to:@return diff --git a/src/test/ref/type-truncate.log b/src/test/ref/type-truncate.log new file mode 100644 index 000000000..850ada113 --- /dev/null +++ b/src/test/ref/type-truncate.log @@ -0,0 +1,157 @@ + +CONTROL FLOW GRAPH SSA + +void main() +main: scope:[main] from __start + main::b#0 = (byte)main::w + main::screen[0] = main::b#0 + to:main::@return +main::@return: scope:[main] from main + return + to:@return + +void __start() +__start: scope:[__start] from + call main + to:__start::@1 +__start::@1: scope:[__start] from __start + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + return + to:@return + +SYMBOL TABLE SSA +void __start() +void main() +byte main::b +byte main::b#0 +constant byte* const main::screen = (byte*)$400 +constant word main::w = $1388 + +Adding number conversion cast (unumber) 0 in main::screen[0] = main::b#0 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant right-side identified [0] main::b#0 = (byte)main::w +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant main::b#0 = (byte)main::w +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero main::screen in [1] main::screen[0] = main::b#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Removing unused procedure __start +Removing unused procedure block __start +Removing unused procedure block __start::@1 +Removing unused procedure block __start::@return +Successful SSA optimization PassNEliminateEmptyStart +CALL GRAPH + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes + +FINAL CONTROL FLOW GRAPH + +void main() +main: scope:[main] from + [0] *main::screen = main::b#0 + to:main::@return +main::@return: scope:[main] from main + [1] return + to:@return + + +VARIABLE REGISTER WEIGHTS +void main() +byte main::b + +Initial phi equivalence classes +Complete equivalence classes +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] *main::screen = main::b#0 [ ] ( [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 15 combination +Uplifting [] best 15 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Type match bytes can be assigned from integers without issue + // Upstart + // Commodore 64 PRG executable file +.file [name="type-truncate.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + // Global Constants & labels +.segment Code + // main +main: { + .const w = $1388 + .const b = $ff&w + .label screen = $400 + // [0] *main::screen = main::b#0 -- _deref_pbuc1=vbuc2 + lda #b + sta screen + jmp __breturn + // main::@return + __breturn: + // [1] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +void main() +byte main::b +constant byte main::b#0 b = (byte)main::w +constant byte* const main::screen = (byte*) 1024 +constant word main::w = $1388 + + + +FINAL ASSEMBLER +Score: 12 + + // File Comments +// Type match bytes can be assigned from integers without issue + // Upstart + // Commodore 64 PRG executable file +.file [name="type-truncate.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) + // Global Constants & labels +.segment Code + // main +main: { + .const w = $1388 + .const b = $ff&w + .label screen = $400 + // screen[0] = b + // [0] *main::screen = main::b#0 -- _deref_pbuc1=vbuc2 + lda #b + sta screen + // main::@return + // } + // [1] return + rts +} + // File Data + diff --git a/src/test/ref/type-truncate.sym b/src/test/ref/type-truncate.sym new file mode 100644 index 000000000..633a077ce --- /dev/null +++ b/src/test/ref/type-truncate.sym @@ -0,0 +1,6 @@ +void main() +byte main::b +constant byte main::b#0 b = (byte)main::w +constant byte* const main::screen = (byte*) 1024 +constant word main::w = $1388 +