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 a946a916c..60cd039cc 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java @@ -124,7 +124,7 @@ public class Procedure extends Scope { public List getParameters() { ArrayList parameters = new ArrayList<>(); for(String name : parameterNames) { - parameters.add(this.getLocalVariable(name)); + parameters.add(this.getLocalVar(name)); } return parameters; } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index ca800a93d..012f95ef2 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -45,6 +45,11 @@ public class TestPrograms { } + @Test + public void testFunctionPointerProblem1() throws IOException, URISyntaxException { + compileAndCompare("function-pointer-problem-1.c"); + } + @Test public void testInlineKickasmUsesProblem() throws IOException, URISyntaxException { compileAndCompare("inline-kickasm-uses-problem.c"); @@ -3098,6 +3103,11 @@ public class TestPrograms { compileAndCompare("pointer-pointer-1.c"); } + @Test + public void testFunctionPointerNoargCall14() throws IOException, URISyntaxException { + compileAndCompare("function-pointer-noarg-call-14.c"); + } + @Test public void testFunctionPointerNoargCall13() throws IOException, URISyntaxException { compileAndCompare("function-pointer-noarg-call-13.c"); diff --git a/src/test/kc/function-pointer-noarg-call-14.c b/src/test/kc/function-pointer-noarg-call-14.c new file mode 100644 index 000000000..dbe1948e3 --- /dev/null +++ b/src/test/kc/function-pointer-noarg-call-14.c @@ -0,0 +1,22 @@ +// Tests trouble passing a function pointer + +#include +#include +#include + +void f1(void()* fn) { + (*fn)(); +} + +void hello() { + printf("hello "); +} + +void world() { + printf("world!"); +} + +void main() { + f1(&hello); + f1(&world); +} diff --git a/src/test/kc/function-pointer-problem-1.c b/src/test/kc/function-pointer-problem-1.c new file mode 100644 index 000000000..c8328d0e7 --- /dev/null +++ b/src/test/kc/function-pointer-problem-1.c @@ -0,0 +1,25 @@ +// The following casuses an exception in pass 2 +// https://gitlab.com/camelot/kickc/-/issues/561 + +char const * r = 0x8000; + +void main() { + enableDLI(&fn1); +} + +void fn1() { + *r = 1; +} + +void enableDLI(__ma void *dliptr) { + asm { + lda #dliptr + sta dlivec+1 + + jmp !+ + dlivec: .byte 0, 0 + !: + } +} diff --git a/src/test/ref/function-pointer-noarg-call-14.asm b/src/test/ref/function-pointer-noarg-call-14.asm new file mode 100644 index 000000000..14920f75d --- /dev/null +++ b/src/test/ref/function-pointer-noarg-call-14.asm @@ -0,0 +1,305 @@ +// Tests trouble passing a function pointer +.pc = $801 "Basic" +:BasicUpstart(__start) +.pc = $80d "Program" + .const LIGHT_BLUE = $e + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $400 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = 8 + // The current cursor y-position + .label conio_cursor_y = 9 + // The current text cursor line start + .label conio_line_text = $a + // The current color cursor line start + .label conio_line_color = $c +__start: { + // conio_cursor_x = 0 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y = 0 + sta.z conio_cursor_y + // conio_line_text = CONIO_SCREEN_TEXT + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // conio_line_color = CONIO_SCREEN_COLORS + lda #COLORRAM + sta.z conio_line_color+1 + jsr main + rts +} +world: { + // printf("world!") + lda #s + sta.z cputs.s+1 + jsr cputs + // } + rts + s: .text "world!" + .byte 0 +} +hello: { + // printf("hello ") + lda #s + sta.z cputs.s+1 + jsr cputs + // } + rts + s: .text "hello " + .byte 0 +} +main: { + // f1(&hello) + lda #hello + sta.z f1.fn+1 + jsr f1 + // f1(&world) + lda #world + sta.z f1.fn+1 + jsr f1 + // } + rts +} +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label s = 2 + __b1: + // while(c=*s++) + ldy #0 + lda (s),y + inc.z s + bne !+ + inc.z s+1 + !: + cmp #0 + bne __b2 + // } + rts + __b2: + // cputc(c) + jsr cputc + jmp __b1 +} +// f1(void()* zp(4) fn) +f1: { + .label fn = 4 + // (*fn)() + jsr bi_fn + // } + rts + bi_fn: + jmp (fn) +} +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte register(A) c) +cputc: { + // if(c=='\n') + cmp #'\n' + beq __b1 + // conio_line_text[conio_cursor_x] = c + ldy.z conio_cursor_x + sta (conio_line_text),y + // conio_line_color[conio_cursor_x] = conio_textcolor + lda #LIGHT_BLUE + sta (conio_line_color),y + // if(++conio_cursor_x==CONIO_WIDTH) + inc.z conio_cursor_x + lda #$28 + cmp.z conio_cursor_x + bne __breturn + // cputln() + jsr cputln + __breturn: + // } + rts + __b1: + // cputln() + jsr cputln + rts +} +// Print a newline +cputln: { + // conio_line_text += CONIO_WIDTH + lda #$28 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // conio_line_color += CONIO_WIDTH + lda #$28 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // conio_cursor_x = 0 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y++; + inc.z conio_cursor_y + // cscroll() + jsr cscroll + // } + rts +} +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // if(conio_cursor_y==CONIO_HEIGHT) + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // memcpy(CONIO_SCREEN_TEXT, CONIO_SCREEN_TEXT+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + lda #DEFAULT_SCREEN+$28 + sta.z memcpy.source+1 + jsr memcpy + // memcpy(CONIO_SCREEN_COLORS, CONIO_SCREEN_COLORS+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + lda #COLORRAM + sta.z memcpy.destination+1 + lda #COLORRAM+$28 + sta.z memcpy.source+1 + jsr memcpy + // memset(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH) + ldx #' ' + lda #DEFAULT_SCREEN+$19*$28-$28 + sta.z memset.str+1 + jsr memset + // memset(CONIO_SCREEN_COLORS+CONIO_BYTES-CONIO_WIDTH, conio_textcolor, CONIO_WIDTH) + ldx #LIGHT_BLUE + lda #COLORRAM+$19*$28-$28 + sta.z memset.str+1 + jsr memset + // conio_line_text -= CONIO_WIDTH + sec + lda.z conio_line_text + sbc #$28 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // conio_line_color -= CONIO_WIDTH + sec + lda.z conio_line_color + sbc #$28 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // conio_cursor_y--; + dec.z conio_cursor_y + __breturn: + // } + rts +} +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp($10) destination, void* zp(6) source) +memcpy: { + .label src_end = $e + .label dst = $10 + .label src = 6 + .label source = 6 + .label destination = $10 + // src_end = (char*)source+num + clc + lda.z source + adc #<$19*$28-$28 + sta.z src_end + lda.z source+1 + adc #>$19*$28-$28 + sta.z src_end+1 + __b1: + // while(src!=src_end) + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + // } + rts + __b2: + // *dst++ = *src++ + ldy #0 + lda (src),y + sta (dst),y + // *dst++ = *src++; + inc.z dst + bne !+ + inc.z dst+1 + !: + inc.z src + bne !+ + inc.z src+1 + !: + jmp __b1 +} +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp(6) str, byte register(X) c) +memset: { + .label end = $10 + .label dst = 6 + .label str = 6 + // end = (char*)str + num + lda #$28 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + __b2: + // for(char* dst = str; dst!=end; dst++) + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + // } + rts + __b3: + // *dst = c + txa + ldy #0 + sta (dst),y + // for(char* dst = str; dst!=end; dst++) + inc.z dst + bne !+ + inc.z dst+1 + !: + jmp __b2 +} diff --git a/src/test/ref/function-pointer-noarg-call-14.cfg b/src/test/ref/function-pointer-noarg-call-14.cfg new file mode 100644 index 000000000..8f8e2f7dd --- /dev/null +++ b/src/test/ref/function-pointer-noarg-call-14.cfg @@ -0,0 +1,183 @@ + +void __start() +__start: scope:[__start] from + [0] phi() + to:__start::__init1 +__start::__init1: scope:[__start] from __start + [1] conio_cursor_x = 0 + [2] conio_cursor_y = 0 + [3] conio_line_text = DEFAULT_SCREEN + [4] conio_line_color = COLORRAM + to:__start::@1 +__start::@1: scope:[__start] from __start::__init1 + [5] phi() + [6] call main + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + [7] return + to:@return + +void world() +world: scope:[world] from + [8] phi() + [9] call cputs + to:world::@return +world::@return: scope:[world] from world + [10] return + to:@return + +void hello() +hello: scope:[hello] from + [11] phi() + [12] call cputs + to:hello::@return +hello::@return: scope:[hello] from hello + [13] return + to:@return + +void main() +main: scope:[main] from __start::@1 + [14] phi() + [15] call f1 + to:main::@1 +main::@1: scope:[main] from main + [16] phi() + [17] call f1 + to:main::@return +main::@return: scope:[main] from main::@1 + [18] return + to:@return + +void cputs(to_nomodify byte* cputs::s) +cputs: scope:[cputs] from hello world + [19] cputs::s#4 = phi( hello/hello::s, world/world::s ) + to:cputs::@1 +cputs::@1: scope:[cputs] from cputs cputs::@2 + [20] cputs::s#3 = phi( cputs/cputs::s#4, cputs::@2/cputs::s#0 ) + [21] cputs::c#1 = *cputs::s#3 + [22] cputs::s#0 = ++ cputs::s#3 + [23] if(0!=cputs::c#1) goto cputs::@2 + to:cputs::@return +cputs::@return: scope:[cputs] from cputs::@1 + [24] return + to:@return +cputs::@2: scope:[cputs] from cputs::@1 + [25] cputc::c#0 = cputs::c#1 + [26] call cputc + to:cputs::@1 + +void f1(void()* f1::fn) +f1: scope:[f1] from main main::@1 + [27] f1::fn#2 = phi( main/&hello, main::@1/&world ) + [28] call *f1::fn#2 + to:f1::@return +f1::@return: scope:[f1] from f1 + [29] return + to:@return + +void cputc(byte cputc::c) +cputc: scope:[cputc] from cputs::@2 + [30] if(cputc::c#0==' +') goto cputc::@1 + to:cputc::@2 +cputc::@2: scope:[cputc] from cputc + [31] conio_line_text[conio_cursor_x] = cputc::c#0 + [32] conio_line_color[conio_cursor_x] = LIGHT_BLUE + [33] conio_cursor_x = ++ conio_cursor_x + [34] if(conio_cursor_x!=$28) goto cputc::@return + to:cputc::@3 +cputc::@3: scope:[cputc] from cputc::@2 + [35] phi() + [36] call cputln + to:cputc::@return +cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@3 + [37] return + to:@return +cputc::@1: scope:[cputc] from cputc + [38] phi() + [39] call cputln + to:cputc::@return + +void cputln() +cputln: scope:[cputln] from cputc::@1 cputc::@3 + [40] conio_line_text = conio_line_text + $28 + [41] conio_line_color = conio_line_color + $28 + [42] conio_cursor_x = 0 + [43] conio_cursor_y = ++ conio_cursor_y + [44] call cscroll + to:cputln::@return +cputln::@return: scope:[cputln] from cputln + [45] return + to:@return + +void cscroll() +cscroll: scope:[cscroll] from cputln + [46] if(conio_cursor_y!=$19) goto cscroll::@return + to:cscroll::@1 +cscroll::@1: scope:[cscroll] from cscroll + [47] phi() + [48] call memcpy + to:cscroll::@2 +cscroll::@2: scope:[cscroll] from cscroll::@1 + [49] phi() + [50] call memcpy + to:cscroll::@3 +cscroll::@3: scope:[cscroll] from cscroll::@2 + [51] phi() + [52] call memset + to:cscroll::@4 +cscroll::@4: scope:[cscroll] from cscroll::@3 + [53] phi() + [54] call memset + to:cscroll::@5 +cscroll::@5: scope:[cscroll] from cscroll::@4 + [55] conio_line_text = conio_line_text - $28 + [56] conio_line_color = conio_line_color - $28 + [57] conio_cursor_y = -- conio_cursor_y + to:cscroll::@return +cscroll::@return: scope:[cscroll] from cscroll cscroll::@5 + [58] return + to:@return + +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +memcpy: scope:[memcpy] from cscroll::@1 cscroll::@2 + [59] memcpy::destination#2 = phi( cscroll::@1/(void*)DEFAULT_SCREEN, cscroll::@2/(void*)COLORRAM ) + [59] memcpy::source#2 = phi( cscroll::@1/(void*)DEFAULT_SCREEN+$28, cscroll::@2/(void*)COLORRAM+$28 ) + [60] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28 + [61] memcpy::src#4 = (byte*)memcpy::source#2 + [62] memcpy::dst#4 = (byte*)memcpy::destination#2 + to:memcpy::@1 +memcpy::@1: scope:[memcpy] from memcpy memcpy::@2 + [63] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 ) + [63] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 ) + [64] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 + to:memcpy::@return +memcpy::@return: scope:[memcpy] from memcpy::@1 + [65] return + to:@return +memcpy::@2: scope:[memcpy] from memcpy::@1 + [66] *memcpy::dst#2 = *memcpy::src#2 + [67] memcpy::dst#1 = ++ memcpy::dst#2 + [68] memcpy::src#1 = ++ memcpy::src#2 + to:memcpy::@1 + +void* memset(void* memset::str , byte memset::c , word memset::num) +memset: scope:[memset] from cscroll::@3 cscroll::@4 + [69] memset::c#4 = phi( cscroll::@3/' ', cscroll::@4/LIGHT_BLUE ) + [69] memset::str#3 = phi( cscroll::@3/(void*)DEFAULT_SCREEN+(word)$19*$28-$28, cscroll::@4/(void*)COLORRAM+(word)$19*$28-$28 ) + to:memset::@1 +memset::@1: scope:[memset] from memset + [70] memset::end#0 = (byte*)memset::str#3 + $28 + [71] memset::dst#4 = (byte*)memset::str#3 + to:memset::@2 +memset::@2: scope:[memset] from memset::@1 memset::@3 + [72] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 ) + [73] if(memset::dst#2!=memset::end#0) goto memset::@3 + to:memset::@return +memset::@return: scope:[memset] from memset::@2 + [74] return + to:@return +memset::@3: scope:[memset] from memset::@2 + [75] *memset::dst#2 = memset::c#4 + [76] memset::dst#1 = ++ memset::dst#2 + to:memset::@2 diff --git a/src/test/ref/function-pointer-noarg-call-14.log b/src/test/ref/function-pointer-noarg-call-14.log new file mode 100644 index 000000000..05749dafc --- /dev/null +++ b/src/test/ref/function-pointer-noarg-call-14.log @@ -0,0 +1,2312 @@ +Fixing struct type size struct printf_buffer_number to 12 +Fixing struct type size struct printf_buffer_number to 12 +Fixing struct type SIZE_OF struct printf_buffer_number to 12 +Fixing struct type SIZE_OF struct printf_buffer_number to 12 +Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx +Inlined call call __init +Eliminating unused variable with no statement printf_buffer +Eliminating unused variable with no statement hello::$0 +Eliminating unused variable with no statement world::$0 + +CONTROL FLOW GRAPH SSA + +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +memcpy: scope:[memcpy] from cscroll::@3 cscroll::@4 + memcpy::num#2 = phi( cscroll::@3/memcpy::num#0, cscroll::@4/memcpy::num#1 ) + memcpy::destination#2 = phi( cscroll::@3/memcpy::destination#0, cscroll::@4/memcpy::destination#1 ) + memcpy::source#2 = phi( cscroll::@3/memcpy::source#0, cscroll::@4/memcpy::source#1 ) + memcpy::src#0 = ((byte*)) memcpy::source#2 + memcpy::dst#0 = ((byte*)) memcpy::destination#2 + memcpy::$2 = (byte*)memcpy::source#2 + memcpy::$0 = memcpy::$2 + memcpy::num#2 + memcpy::src_end#0 = memcpy::$0 + to:memcpy::@1 +memcpy::@1: scope:[memcpy] from memcpy memcpy::@2 + memcpy::destination#4 = phi( memcpy/memcpy::destination#2, memcpy::@2/memcpy::destination#5 ) + memcpy::dst#3 = phi( memcpy/memcpy::dst#0, memcpy::@2/memcpy::dst#1 ) + memcpy::src_end#1 = phi( memcpy/memcpy::src_end#0, memcpy::@2/memcpy::src_end#2 ) + memcpy::src#2 = phi( memcpy/memcpy::src#0, memcpy::@2/memcpy::src#1 ) + memcpy::$1 = memcpy::src#2 != memcpy::src_end#1 + if(memcpy::$1) goto memcpy::@2 + to:memcpy::@3 +memcpy::@2: scope:[memcpy] from memcpy::@1 + memcpy::destination#5 = phi( memcpy::@1/memcpy::destination#4 ) + memcpy::src_end#2 = phi( memcpy::@1/memcpy::src_end#1 ) + memcpy::dst#2 = phi( memcpy::@1/memcpy::dst#3 ) + memcpy::src#3 = phi( memcpy::@1/memcpy::src#2 ) + *memcpy::dst#2 = *memcpy::src#3 + memcpy::dst#1 = ++ memcpy::dst#2 + memcpy::src#1 = ++ memcpy::src#3 + to:memcpy::@1 +memcpy::@3: scope:[memcpy] from memcpy::@1 + memcpy::destination#3 = phi( memcpy::@1/memcpy::destination#4 ) + memcpy::return#0 = memcpy::destination#3 + to:memcpy::@return +memcpy::@return: scope:[memcpy] from memcpy::@3 + memcpy::return#4 = phi( memcpy::@3/memcpy::return#0 ) + memcpy::return#1 = memcpy::return#4 + return + to:@return + +void* memset(void* memset::str , byte memset::c , word memset::num) +memset: scope:[memset] from cscroll::@5 cscroll::@6 + memset::c#5 = phi( cscroll::@5/memset::c#0, cscroll::@6/memset::c#1 ) + memset::str#4 = phi( cscroll::@5/memset::str#0, cscroll::@6/memset::str#1 ) + memset::num#2 = phi( cscroll::@5/memset::num#0, cscroll::@6/memset::num#1 ) + memset::$0 = memset::num#2 > 0 + memset::$1 = ! memset::$0 + if(memset::$1) goto memset::@1 + to:memset::@2 +memset::@1: scope:[memset] from memset memset::@3 + memset::str#2 = phi( memset/memset::str#4, memset::@3/memset::str#5 ) + memset::return#0 = memset::str#2 + to:memset::@return +memset::@2: scope:[memset] from memset + memset::c#4 = phi( memset/memset::c#5 ) + memset::num#3 = phi( memset/memset::num#2 ) + memset::str#3 = phi( memset/memset::str#4 ) + memset::$4 = (byte*)memset::str#3 + memset::$2 = memset::$4 + memset::num#3 + memset::end#0 = memset::$2 + memset::dst#0 = ((byte*)) memset::str#3 + to:memset::@3 +memset::@3: scope:[memset] from memset::@2 memset::@4 + memset::c#3 = phi( memset::@2/memset::c#4, memset::@4/memset::c#2 ) + memset::str#5 = phi( memset::@2/memset::str#3, memset::@4/memset::str#6 ) + memset::end#1 = phi( memset::@2/memset::end#0, memset::@4/memset::end#2 ) + memset::dst#2 = phi( memset::@2/memset::dst#0, memset::@4/memset::dst#1 ) + memset::$3 = memset::dst#2 != memset::end#1 + if(memset::$3) goto memset::@4 + to:memset::@1 +memset::@4: scope:[memset] from memset::@3 + memset::str#6 = phi( memset::@3/memset::str#5 ) + memset::end#2 = phi( memset::@3/memset::end#1 ) + memset::dst#3 = phi( memset::@3/memset::dst#2 ) + memset::c#2 = phi( memset::@3/memset::c#3 ) + *memset::dst#3 = memset::c#2 + memset::dst#1 = ++ memset::dst#3 + to:memset::@3 +memset::@return: scope:[memset] from memset::@1 + memset::return#4 = phi( memset::@1/memset::return#0 ) + memset::return#1 = memset::return#4 + return + to:@return + +void gotoxy(byte gotoxy::x , byte gotoxy::y) +gotoxy: scope:[gotoxy] from cscroll::@2 + gotoxy::x#4 = phi( cscroll::@2/gotoxy::x#1 ) + gotoxy::y#2 = phi( cscroll::@2/gotoxy::y#1 ) + gotoxy::$0 = gotoxy::y#2 > $19 + gotoxy::$1 = ! gotoxy::$0 + if(gotoxy::$1) goto gotoxy::@1 + to:gotoxy::@3 +gotoxy::@1: scope:[gotoxy] from gotoxy gotoxy::@3 + gotoxy::y#4 = phi( gotoxy/gotoxy::y#2, gotoxy::@3/gotoxy::y#0 ) + gotoxy::x#2 = phi( gotoxy/gotoxy::x#4, gotoxy::@3/gotoxy::x#5 ) + gotoxy::$2 = gotoxy::x#2 >= $28 + gotoxy::$3 = ! gotoxy::$2 + if(gotoxy::$3) goto gotoxy::@2 + to:gotoxy::@4 +gotoxy::@3: scope:[gotoxy] from gotoxy + gotoxy::x#5 = phi( gotoxy/gotoxy::x#4 ) + gotoxy::y#0 = 0 + to:gotoxy::@1 +gotoxy::@2: scope:[gotoxy] from gotoxy::@1 gotoxy::@4 + gotoxy::y#3 = phi( gotoxy::@1/gotoxy::y#4, gotoxy::@4/gotoxy::y#5 ) + gotoxy::x#3 = phi( gotoxy::@1/gotoxy::x#2, gotoxy::@4/gotoxy::x#0 ) + conio_cursor_x = gotoxy::x#3 + conio_cursor_y = gotoxy::y#3 + gotoxy::$7 = (word)gotoxy::y#3 + gotoxy::$4 = gotoxy::$7 * $28 + gotoxy::line_offset#0 = gotoxy::$4 + gotoxy::$5 = CONIO_SCREEN_TEXT + gotoxy::line_offset#0 + conio_line_text = gotoxy::$5 + gotoxy::$6 = CONIO_SCREEN_COLORS + gotoxy::line_offset#0 + conio_line_color = gotoxy::$6 + to:gotoxy::@return +gotoxy::@4: scope:[gotoxy] from gotoxy::@1 + gotoxy::y#5 = phi( gotoxy::@1/gotoxy::y#4 ) + gotoxy::x#0 = 0 + to:gotoxy::@2 +gotoxy::@return: scope:[gotoxy] from gotoxy::@2 + return + to:@return + +void cputc(byte cputc::c) +cputc: scope:[cputc] from cputs::@2 + cputc::c#1 = phi( cputs::@2/cputc::c#0 ) + cputc::$0 = cputc::c#1 == ' +' + if(cputc::$0) goto cputc::@1 + to:cputc::@2 +cputc::@1: scope:[cputc] from cputc + call cputln + to:cputc::@4 +cputc::@4: scope:[cputc] from cputc::@1 + to:cputc::@return +cputc::@2: scope:[cputc] from cputc + cputc::c#2 = phi( cputc/cputc::c#1 ) + conio_line_text[conio_cursor_x] = cputc::c#2 + conio_line_color[conio_cursor_x] = conio_textcolor + conio_cursor_x = ++ conio_cursor_x + cputc::$1 = conio_cursor_x == $28 + cputc::$2 = ! cputc::$1 + if(cputc::$2) goto cputc::@return + to:cputc::@3 +cputc::@3: scope:[cputc] from cputc::@2 + call cputln + to:cputc::@5 +cputc::@5: scope:[cputc] from cputc::@3 + to:cputc::@return +cputc::@return: scope:[cputc] from cputc::@2 cputc::@4 cputc::@5 + return + to:@return + +void cputln() +cputln: scope:[cputln] from cputc::@1 cputc::@3 + conio_line_text = conio_line_text + $28 + conio_line_color = conio_line_color + $28 + conio_cursor_x = 0 + conio_cursor_y = ++ conio_cursor_y + call cscroll + to:cputln::@1 +cputln::@1: scope:[cputln] from cputln + to:cputln::@return +cputln::@return: scope:[cputln] from cputln::@1 + return + to:@return + +void cscroll() +cscroll: scope:[cscroll] from cputln + cscroll::$0 = conio_cursor_y == $19 + cscroll::$1 = ! cscroll::$0 + if(cscroll::$1) goto cscroll::@return + to:cscroll::@1 +cscroll::@1: scope:[cscroll] from cscroll + cscroll::$7 = 0 != conio_scroll_enable + if(cscroll::$7) goto cscroll::@3 + to:cscroll::@2 +cscroll::@3: scope:[cscroll] from cscroll::@1 + memcpy::destination#0 = (void*)CONIO_SCREEN_TEXT + memcpy::source#0 = (void*)CONIO_SCREEN_TEXT+$28 + memcpy::num#0 = $19*$28-$28 + call memcpy + memcpy::return#2 = memcpy::return#1 + to:cscroll::@4 +cscroll::@4: scope:[cscroll] from cscroll::@3 + memcpy::destination#1 = (void*)CONIO_SCREEN_COLORS + memcpy::source#1 = (void*)CONIO_SCREEN_COLORS+$28 + memcpy::num#1 = $19*$28-$28 + call memcpy + memcpy::return#3 = memcpy::return#1 + to:cscroll::@5 +cscroll::@5: scope:[cscroll] from cscroll::@4 + memset::str#0 = (void*)CONIO_SCREEN_TEXT+$19*$28-$28 + memset::c#0 = ' ' + memset::num#0 = $28 + call memset + memset::return#2 = memset::return#1 + to:cscroll::@6 +cscroll::@6: scope:[cscroll] from cscroll::@5 + memset::str#1 = (void*)CONIO_SCREEN_COLORS+$19*$28-$28 + memset::c#1 = conio_textcolor + memset::num#1 = $28 + call memset + memset::return#3 = memset::return#1 + to:cscroll::@7 +cscroll::@7: scope:[cscroll] from cscroll::@6 + conio_line_text = conio_line_text - $28 + conio_line_color = conio_line_color - $28 + conio_cursor_y = -- conio_cursor_y + to:cscroll::@return +cscroll::@2: scope:[cscroll] from cscroll::@1 + gotoxy::x#1 = 0 + gotoxy::y#1 = 0 + call gotoxy + to:cscroll::@8 +cscroll::@8: scope:[cscroll] from cscroll::@2 + to:cscroll::@return +cscroll::@return: scope:[cscroll] from cscroll cscroll::@7 cscroll::@8 + return + to:@return + +void cputs(to_nomodify byte* cputs::s) +cputs: scope:[cputs] from hello world + cputs::s#4 = phi( hello/cputs::s#1, world/cputs::s#2 ) + cputs::c#0 = 0 + to:cputs::@1 +cputs::@1: scope:[cputs] from cputs cputs::@3 + cputs::s#3 = phi( cputs/cputs::s#4, cputs::@3/cputs::s#5 ) + cputs::c#1 = *cputs::s#3 + cputs::$0 = cputs::c#1 + cputs::s#0 = ++ cputs::s#3 + cputs::$2 = 0 != cputs::$0 + if(cputs::$2) goto cputs::@2 + to:cputs::@return +cputs::@2: scope:[cputs] from cputs::@1 + cputs::s#6 = phi( cputs::@1/cputs::s#0 ) + cputs::c#2 = phi( cputs::@1/cputs::c#1 ) + cputc::c#0 = cputs::c#2 + call cputc + to:cputs::@3 +cputs::@3: scope:[cputs] from cputs::@2 + cputs::s#5 = phi( cputs::@2/cputs::s#6 ) + to:cputs::@1 +cputs::@return: scope:[cputs] from cputs::@1 + return + to:@return + +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 + to:f1::@return +f1::@return: scope:[f1] from f1 + return + to:@return + +void hello() +hello: scope:[hello] from + cputs::s#1 = hello::s + call cputs + to:hello::@1 +hello::@1: scope:[hello] from hello + to:hello::@return +hello::@return: scope:[hello] from hello::@1 + return + to:@return + +void world() +world: scope:[world] from + cputs::s#2 = world::s + call cputs + to:world::@1 +world::@1: scope:[world] from world + to:world::@return +world::@return: scope:[world] from world::@1 + return + to:@return + +void main() +main: scope:[main] from __start::@1 + f1::fn#0 = &hello + call f1 + to:main::@1 +main::@1: scope:[main] from main + f1::fn#1 = &world + call f1 + to:main::@2 +main::@2: scope:[main] from main::@1 + to:main::@return +main::@return: scope:[main] from main::@2 + return + to:@return + +void __start() +__start: scope:[__start] from + to:__start::__init1 +__start::__init1: scope:[__start] from __start + conio_cursor_x = 0 + conio_cursor_y = 0 + conio_line_text = CONIO_SCREEN_TEXT + conio_line_color = CONIO_SCREEN_COLORS + conio_textcolor = CONIO_TEXTCOLOR_DEFAULT + conio_scroll_enable = 1 + to:__start::@1 +__start::@1: scope:[__start] from __start::__init1 + call main + to:__start::@2 +__start::@2: scope:[__start] from __start::@1 + to:__start::@return +__start::@return: scope:[__start] from __start::@2 + return + to:@return + +SYMBOL TABLE SSA +const nomodify byte* COLORRAM = (byte*)$d800 +const nomodify byte* CONIO_SCREEN_COLORS = COLORRAM +const nomodify byte* CONIO_SCREEN_TEXT = DEFAULT_SCREEN +const nomodify byte CONIO_TEXTCOLOR_DEFAULT = LIGHT_BLUE +const nomodify byte* DEFAULT_SCREEN = (byte*)$400 +const nomodify byte LIGHT_BLUE = $e +const byte RADIX::BINARY = 2 +const byte RADIX::DECIMAL = $a +const byte RADIX::HEXADECIMAL = $10 +const byte RADIX::OCTAL = 8 +void __start() +byte conio_cursor_x loadstore +byte conio_cursor_y loadstore +byte* conio_line_color loadstore +byte* conio_line_text loadstore +byte conio_scroll_enable loadstore +byte conio_textcolor loadstore +void cputc(byte cputc::c) +bool~ cputc::$0 +bool~ cputc::$1 +bool~ cputc::$2 +byte cputc::c +byte cputc::c#0 +byte cputc::c#1 +byte cputc::c#2 +void cputln() +void cputs(to_nomodify byte* cputs::s) +byte~ cputs::$0 +bool~ cputs::$2 +byte cputs::c +byte cputs::c#0 +byte cputs::c#1 +byte cputs::c#2 +to_nomodify byte* cputs::s +to_nomodify byte* cputs::s#0 +to_nomodify byte* cputs::s#1 +to_nomodify byte* cputs::s#2 +to_nomodify byte* cputs::s#3 +to_nomodify byte* cputs::s#4 +to_nomodify byte* cputs::s#5 +to_nomodify byte* cputs::s#6 +void cscroll() +bool~ cscroll::$0 +bool~ cscroll::$1 +bool~ cscroll::$7 +void f1(void()* f1::fn) +void()* f1::fn +void()* f1::fn#0 +void()* f1::fn#1 +void()* f1::fn#2 +void gotoxy(byte gotoxy::x , byte gotoxy::y) +bool~ gotoxy::$0 +bool~ gotoxy::$1 +bool~ gotoxy::$2 +bool~ gotoxy::$3 +number~ gotoxy::$4 +byte*~ gotoxy::$5 +byte*~ gotoxy::$6 +word~ gotoxy::$7 +word gotoxy::line_offset +word gotoxy::line_offset#0 +byte gotoxy::x +byte gotoxy::x#0 +byte gotoxy::x#1 +byte gotoxy::x#2 +byte gotoxy::x#3 +byte gotoxy::x#4 +byte gotoxy::x#5 +byte gotoxy::y +byte gotoxy::y#0 +byte gotoxy::y#1 +byte gotoxy::y#2 +byte gotoxy::y#3 +byte gotoxy::y#4 +byte gotoxy::y#5 +void hello() +const byte* hello::s[7] = "hello " +void main() +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +byte*~ memcpy::$0 +bool~ memcpy::$1 +byte*~ memcpy::$2 +void* memcpy::destination +void* memcpy::destination#0 +void* memcpy::destination#1 +void* memcpy::destination#2 +void* memcpy::destination#3 +void* memcpy::destination#4 +void* memcpy::destination#5 +byte* memcpy::dst +byte* memcpy::dst#0 +byte* memcpy::dst#1 +byte* memcpy::dst#2 +byte* memcpy::dst#3 +word memcpy::num +word memcpy::num#0 +word memcpy::num#1 +word memcpy::num#2 +void* memcpy::return +void* memcpy::return#0 +void* memcpy::return#1 +void* memcpy::return#2 +void* memcpy::return#3 +void* memcpy::return#4 +void* memcpy::source +void* memcpy::source#0 +void* memcpy::source#1 +void* memcpy::source#2 +byte* memcpy::src +byte* memcpy::src#0 +byte* memcpy::src#1 +byte* memcpy::src#2 +byte* memcpy::src#3 +byte* memcpy::src_end +byte* memcpy::src_end#0 +byte* memcpy::src_end#1 +byte* memcpy::src_end#2 +void* memset(void* memset::str , byte memset::c , word memset::num) +bool~ memset::$0 +bool~ memset::$1 +byte*~ memset::$2 +bool~ memset::$3 +byte*~ memset::$4 +byte memset::c +byte memset::c#0 +byte memset::c#1 +byte memset::c#2 +byte memset::c#3 +byte memset::c#4 +byte memset::c#5 +byte* memset::dst +byte* memset::dst#0 +byte* memset::dst#1 +byte* memset::dst#2 +byte* memset::dst#3 +byte* memset::end +byte* memset::end#0 +byte* memset::end#1 +byte* memset::end#2 +word memset::num +word memset::num#0 +word memset::num#1 +word memset::num#2 +word memset::num#3 +void* memset::return +void* memset::return#0 +void* memset::return#1 +void* memset::return#2 +void* memset::return#3 +void* memset::return#4 +void* memset::str +void* memset::str#0 +void* memset::str#1 +void* memset::str#2 +void* memset::str#3 +void* memset::str#4 +void* memset::str#5 +void* memset::str#6 +void world() +const byte* world::s[7] = "world!" + +Adding number conversion cast (unumber) 0 in memset::$0 = memset::num#2 > 0 +Adding number conversion cast (unumber) $19 in gotoxy::$0 = gotoxy::y#2 > $19 +Adding number conversion cast (unumber) $28 in gotoxy::$2 = gotoxy::x#2 >= $28 +Adding number conversion cast (unumber) 0 in gotoxy::y#0 = 0 +Adding number conversion cast (unumber) $28 in gotoxy::$4 = gotoxy::$7 * $28 +Adding number conversion cast (unumber) gotoxy::$4 in gotoxy::$4 = gotoxy::$7 * (unumber)$28 +Adding number conversion cast (unumber) 0 in gotoxy::x#0 = 0 +Adding number conversion cast (unumber) $28 in cputc::$1 = conio_cursor_x == $28 +Adding number conversion cast (unumber) $28 in conio_line_text = conio_line_text + $28 +Adding number conversion cast (unumber) $28 in conio_line_color = conio_line_color + $28 +Adding number conversion cast (unumber) 0 in conio_cursor_x = 0 +Adding number conversion cast (unumber) $19 in cscroll::$0 = conio_cursor_y == $19 +Adding number conversion cast (unumber) 0 in cscroll::$7 = 0 != conio_scroll_enable +Adding number conversion cast (unumber) $28 in memcpy::source#0 = (void*)CONIO_SCREEN_TEXT+$28 +Adding number conversion cast (unumber) $19*$28-$28 in memcpy::num#0 = $19*$28-$28 +Adding number conversion cast (unumber) $28 in memcpy::source#1 = (void*)CONIO_SCREEN_COLORS+$28 +Adding number conversion cast (unumber) $19*$28-$28 in memcpy::num#1 = $19*$28-$28 +Adding number conversion cast (unumber) $28 in memset::str#0 = (void*)CONIO_SCREEN_TEXT+$19*$28-$28 +Adding number conversion cast (unumber) $19*$28 in memset::str#0 = (void*)CONIO_SCREEN_TEXT+$19*$28-(unumber)$28 +Adding number conversion cast (unumber) $28 in memset::num#0 = $28 +Adding number conversion cast (unumber) $28 in memset::str#1 = (void*)CONIO_SCREEN_COLORS+$19*$28-$28 +Adding number conversion cast (unumber) $19*$28 in memset::str#1 = (void*)CONIO_SCREEN_COLORS+$19*$28-(unumber)$28 +Adding number conversion cast (unumber) $28 in memset::num#1 = $28 +Adding number conversion cast (unumber) $28 in conio_line_text = conio_line_text - $28 +Adding number conversion cast (unumber) $28 in conio_line_color = conio_line_color - $28 +Adding number conversion cast (unumber) 0 in gotoxy::x#1 = 0 +Adding number conversion cast (unumber) 0 in gotoxy::y#1 = 0 +Adding number conversion cast (unumber) 0 in cputs::$2 = 0 != cputs::$0 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast memcpy::src#0 = (byte*)memcpy::source#2 +Inlining cast memcpy::dst#0 = (byte*)memcpy::destination#2 +Inlining cast memset::dst#0 = (byte*)memset::str#3 +Inlining cast gotoxy::y#0 = (unumber)0 +Inlining cast gotoxy::x#0 = (unumber)0 +Inlining cast conio_cursor_x = (unumber)0 +Inlining cast memcpy::num#0 = (unumber)$19*$28-$28 +Inlining cast memcpy::num#1 = (unumber)$19*$28-$28 +Inlining cast memset::num#0 = (unumber)$28 +Inlining cast memset::num#1 = (unumber)$28 +Inlining cast gotoxy::x#1 = (unumber)0 +Inlining cast gotoxy::y#1 = (unumber)0 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 55296 +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast $19 +Simplifying constant integer cast $28 +Simplifying constant integer cast 0 +Simplifying constant integer cast $28 +Simplifying constant integer cast 0 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast 0 +Simplifying constant integer cast $19 +Simplifying constant integer cast 0 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast $28 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type 0 +Finalized unsigned number type $19 +Finalized unsigned number type $28 +Finalized unsigned number type 0 +Finalized unsigned number type $28 +Finalized unsigned number type 0 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type 0 +Finalized unsigned number type $19 +Finalized unsigned number type 0 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type $28 +Finalized unsigned number type 0 +Finalized unsigned number type 0 +Finalized unsigned number type 0 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to word in gotoxy::$4 = gotoxy::$7 * $28 +Inversing boolean not [20] memset::$1 = memset::num#2 <= 0 from [19] memset::$0 = memset::num#2 > 0 +Inversing boolean not [40] gotoxy::$1 = gotoxy::y#2 <= $19 from [39] gotoxy::$0 = gotoxy::y#2 > $19 +Inversing boolean not [44] gotoxy::$3 = gotoxy::x#2 < $28 from [43] gotoxy::$2 = gotoxy::x#2 >= $28 +Inversing boolean not [70] cputc::$2 = conio_cursor_x != $28 from [69] cputc::$1 = conio_cursor_x == $28 +Inversing boolean not [81] cscroll::$1 = conio_cursor_y != $19 from [80] cscroll::$0 = conio_cursor_y == $19 +Successful SSA optimization Pass2UnaryNotSimplification +Alias candidate removed (volatile)conio_line_text = gotoxy::$5 +Alias candidate removed (volatile)conio_line_color = gotoxy::$6 +Alias memcpy::src_end#0 = memcpy::$0 +Alias memcpy::src#2 = memcpy::src#3 +Alias memcpy::dst#2 = memcpy::dst#3 +Alias memcpy::src_end#1 = memcpy::src_end#2 +Alias memcpy::destination#3 = memcpy::destination#5 memcpy::destination#4 memcpy::return#0 memcpy::return#4 memcpy::return#1 +Alias memset::return#0 = memset::str#2 memset::return#4 memset::return#1 +Alias memset::str#3 = memset::str#4 +Alias memset::num#2 = memset::num#3 +Alias memset::c#4 = memset::c#5 +Alias memset::end#0 = memset::$2 +Alias memset::c#2 = memset::c#3 +Alias memset::dst#2 = memset::dst#3 +Alias memset::end#1 = memset::end#2 +Alias memset::str#5 = memset::str#6 +Alias gotoxy::x#4 = gotoxy::x#5 +Alias gotoxy::line_offset#0 = gotoxy::$4 +Alias gotoxy::y#4 = gotoxy::y#5 +Alias cputc::c#1 = cputc::c#2 +Alias cputs::c#1 = cputs::$0 cputs::c#2 +Alias cputs::s#0 = cputs::s#6 cputs::s#5 +Successful SSA optimization Pass2AliasElimination +Alias candidate removed (volatile)conio_line_text = gotoxy::$5 +Alias candidate removed (volatile)conio_line_color = gotoxy::$6 +Alias gotoxy::x#2 = gotoxy::x#4 +Alias gotoxy::y#3 = gotoxy::y#4 +Successful SSA optimization Pass2AliasElimination +Alias candidate removed (volatile)conio_line_text = gotoxy::$5 +Alias candidate removed (volatile)conio_line_color = gotoxy::$6 +Identical Phi Values memcpy::src_end#1 memcpy::src_end#0 +Identical Phi Values memcpy::destination#3 memcpy::destination#2 +Identical Phi Values memset::end#1 memset::end#0 +Identical Phi Values memset::str#5 memset::str#3 +Identical Phi Values memset::c#2 memset::c#4 +Identical Phi Values gotoxy::y#2 gotoxy::y#1 +Identical Phi Values gotoxy::x#2 gotoxy::x#1 +Identical Phi Values cputc::c#1 cputc::c#0 +Successful SSA optimization Pass2IdenticalPhiElimination +Identical Phi Values memset::return#0 memset::str#3 +Successful SSA optimization Pass2IdenticalPhiElimination +Simple Condition memcpy::$1 [7] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 +Simple Condition memset::$1 [14] if(memset::num#2<=0) goto memset::@1 +Simple Condition memset::$3 [21] if(memset::dst#2!=memset::end#0) goto memset::@4 +Simple Condition gotoxy::$1 [27] if(gotoxy::y#1<=$19) goto gotoxy::@1 +Simple Condition gotoxy::$3 [30] if(gotoxy::x#1<$28) goto gotoxy::@2 +Simple Condition cputc::$0 [45] if(cputc::c#0==' +') goto cputc::@1 +Simple Condition cputc::$2 [51] if(conio_cursor_x!=$28) goto cputc::@return +Simple Condition cscroll::$1 [61] if(conio_cursor_y!=$19) goto cscroll::@return +Simple Condition cscroll::$7 [63] if(0!=conio_scroll_enable) goto cscroll::@3 +Simple Condition cputs::$2 [97] if(0!=cputs::c#1) goto cputs::@2 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [66] memcpy::num#0 = (unumber)$19*$28-$28 +Constant right-side identified [71] memcpy::num#1 = (unumber)$19*$28-$28 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant gotoxy::y#0 = 0 +Constant gotoxy::x#0 = 0 +Constant memcpy::destination#0 = (void*)CONIO_SCREEN_TEXT +Constant memcpy::source#0 = (void*)CONIO_SCREEN_TEXT+$28 +Constant memcpy::num#0 = (unumber)$19*$28-$28 +Constant memcpy::destination#1 = (void*)CONIO_SCREEN_COLORS +Constant memcpy::source#1 = (void*)CONIO_SCREEN_COLORS+$28 +Constant memcpy::num#1 = (unumber)$19*$28-$28 +Constant memset::str#0 = (void*)CONIO_SCREEN_TEXT+(word)$19*$28-$28 +Constant memset::c#0 = ' ' +Constant memset::num#0 = $28 +Constant memset::str#1 = (void*)CONIO_SCREEN_COLORS+(word)$19*$28-$28 +Constant memset::num#1 = $28 +Constant gotoxy::x#1 = 0 +Constant gotoxy::y#1 = 0 +Constant cputs::c#0 = 0 +Constant cputs::s#1 = hello::s +Constant cputs::s#2 = world::s +Constant f1::fn#0 = &hello +Constant f1::fn#1 = &world +Constant conio_textcolor = CONIO_TEXTCOLOR_DEFAULT +Constant conio_scroll_enable = 1 +Successful SSA optimization Pass2ConstantIdentification +Constant memset::c#1 = conio_textcolor +Successful SSA optimization Pass2ConstantIdentification +if() condition always true - replacing block destination [27] if(gotoxy::y#1<=$19) goto gotoxy::@1 +if() condition always true - replacing block destination [30] if(gotoxy::x#1<$28) goto gotoxy::@2 +if() condition always true - replacing block destination [63] if(0!=conio_scroll_enable) goto cscroll::@3 +Successful SSA optimization Pass2ConstantIfs +Eliminating unused variable memcpy::return#2 and assignment [48] memcpy::return#2 = memcpy::destination#2 +Eliminating unused variable memcpy::return#3 and assignment [50] memcpy::return#3 = memcpy::destination#2 +Eliminating unused variable memset::return#2 and assignment [52] memset::return#2 = memset::str#3 +Eliminating unused variable memset::return#3 and assignment [54] memset::return#3 = memset::str#3 +Eliminating unused constant cputs::c#0 +Eliminating unused constant conio_scroll_enable +Successful SSA optimization PassNEliminateUnusedVars +Eliminating variable gotoxy::y#3 from unused block gotoxy::@1 +Eliminating variable gotoxy::x#3 from unused block gotoxy::@2 +Eliminating variable gotoxy::$7 from unused block gotoxy::@2 +Eliminating variable gotoxy::line_offset#0 from unused block gotoxy::@2 +Eliminating variable gotoxy::$5 from unused block gotoxy::@2 +Eliminating variable gotoxy::$6 from unused block gotoxy::@2 +Removing unused procedure gotoxy +Removing unused procedure block gotoxy +Removing PHI-reference to removed block (gotoxy) in block gotoxy::@1 +Removing unused procedure block gotoxy::@1 +Removing PHI-reference to removed block (gotoxy::@1) in block gotoxy::@2 +Removing unused procedure block gotoxy::@3 +Removing unused procedure block gotoxy::@2 +Removing unused procedure block gotoxy::@4 +Removing unused procedure block gotoxy::@return +Removing unused block cscroll::@2 +Removing unused block cscroll::@8 +Successful SSA optimization Pass2EliminateUnusedBlocks +Inlining Noop Cast [1] memcpy::src#0 = (byte*)memcpy::source#2 keeping memcpy::source#2 +Inlining Noop Cast [2] memcpy::dst#0 = (byte*)memcpy::destination#2 keeping memcpy::destination#2 +Inlining Noop Cast [3] memcpy::$2 = (byte*)memcpy::source#2 keeping memcpy::source#2 +Inlining Noop Cast [13] memset::$4 = (byte*)memset::str#3 keeping memset::str#3 +Inlining Noop Cast [15] memset::dst#0 = (byte*)memset::str#3 keeping memset::str#3 +Successful SSA optimization Pass2NopCastInlining +Inlining constant with var siblings memcpy::destination#0 +Inlining constant with var siblings memcpy::source#0 +Inlining constant with var siblings memcpy::num#0 +Inlining constant with var siblings memcpy::destination#1 +Inlining constant with var siblings memcpy::source#1 +Inlining constant with var siblings memcpy::num#1 +Inlining constant with var siblings memset::str#0 +Inlining constant with var siblings memset::c#0 +Inlining constant with var siblings memset::num#0 +Inlining constant with var siblings memset::str#1 +Inlining constant with var siblings memset::num#1 +Inlining constant with var siblings memset::c#1 +Inlining constant with var siblings cputs::s#1 +Inlining constant with var siblings cputs::s#2 +Inlining constant with var siblings f1::fn#0 +Inlining constant with var siblings f1::fn#1 +Constant inlined memset::str#1 = (void*)COLORRAM+(word)$19*$28-$28 +Constant inlined memset::str#0 = (void*)DEFAULT_SCREEN+(word)$19*$28-$28 +Constant inlined f1::fn#1 = &world +Constant inlined CONIO_SCREEN_COLORS = COLORRAM +Constant inlined f1::fn#0 = &hello +Constant inlined cputs::s#1 = hello::s +Constant inlined cputs::s#2 = world::s +Constant inlined conio_textcolor = LIGHT_BLUE +Constant inlined memcpy::destination#0 = (void*)DEFAULT_SCREEN +Constant inlined memset::num#1 = $28 +Constant inlined memcpy::destination#1 = (void*)COLORRAM +Constant inlined memset::num#0 = $28 +Constant inlined memcpy::source#0 = (void*)DEFAULT_SCREEN+$28 +Constant inlined memcpy::num#1 = (word)$19*$28-$28 +Constant inlined memcpy::num#0 = (word)$19*$28-$28 +Constant inlined memcpy::source#1 = (void*)COLORRAM+$28 +Constant inlined CONIO_SCREEN_TEXT = DEFAULT_SCREEN +Constant inlined memset::c#0 = ' ' +Constant inlined memset::c#1 = LIGHT_BLUE +Constant inlined CONIO_TEXTCOLOR_DEFAULT = LIGHT_BLUE +Successful SSA optimization Pass2ConstantInlining +Identical Phi Values memcpy::num#2 (word)$19*$28-$28 +Identical Phi Values memset::num#2 $28 +Successful SSA optimization Pass2IdenticalPhiElimination +if() condition always false - eliminating [9] if($28<=0) goto memset::@1 +Successful SSA optimization Pass2ConstantIfs +Adding NOP phi() at start of __start +Adding NOP phi() at start of __start::@1 +Adding NOP phi() at start of __start::@2 +Adding NOP phi() at start of world +Adding NOP phi() at start of world::@1 +Adding NOP phi() at start of hello +Adding NOP phi() at start of hello::@1 +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of main::@2 +Adding NOP phi() at start of cputc::@3 +Adding NOP phi() at start of cputc::@5 +Adding NOP phi() at start of cputc::@1 +Adding NOP phi() at start of cputc::@4 +Adding NOP phi() at start of cputln::@1 +Adding NOP phi() at start of cscroll::@1 +Adding NOP phi() at start of cscroll::@3 +Adding NOP phi() at start of cscroll::@4 +Adding NOP phi() at start of cscroll::@5 +Adding NOP phi() at start of cscroll::@6 +Adding NOP phi() at start of memcpy::@3 +Adding NOP phi() at start of memset::@1 +CALL GRAPH +Calls in [__start] to main:6 +Calls in [world] to cputs:10 +Calls in [hello] to cputs:14 +Calls in [main] to f1:18 f1:20 +Calls in [cputs] to cputc:31 +Calls in [cputc] to cputln:42 cputln:46 +Calls in [cputln] to cscroll:52 +Calls in [cscroll] to memcpy:58 memcpy:60 memset:62 memset:64 + +Created 10 initial phi equivalence classes +Coalesced [24] cputs::s#7 = cputs::s#4 +Coalesced [32] cputs::s#8 = cputs::s#0 +Coalesced [80] memcpy::src#5 = memcpy::src#1 +Coalesced [81] memcpy::dst#5 = memcpy::dst#1 +Coalesced [91] memset::dst#5 = memset::dst#1 +Coalesced down to 9 phi equivalence classes +Culled Empty Block label __start::@2 +Culled Empty Block label world::@1 +Culled Empty Block label hello::@1 +Culled Empty Block label main::@2 +Culled Empty Block label cputs::@3 +Culled Empty Block label cputc::@5 +Culled Empty Block label cputc::@4 +Culled Empty Block label cputln::@1 +Culled Empty Block label cscroll::@1 +Culled Empty Block label memcpy::@3 +Culled Empty Block label memset::@1 +Renumbering block memset::@2 to memset::@1 +Renumbering block memset::@3 to memset::@2 +Renumbering block memset::@4 to memset::@3 +Renumbering block cscroll::@3 to cscroll::@1 +Renumbering block cscroll::@4 to cscroll::@2 +Renumbering block cscroll::@5 to cscroll::@3 +Renumbering block cscroll::@6 to cscroll::@4 +Renumbering block cscroll::@7 to cscroll::@5 +Adding NOP phi() at start of __start +Adding NOP phi() at start of __start::@1 +Adding NOP phi() at start of world +Adding NOP phi() at start of hello +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of cputc::@3 +Adding NOP phi() at start of cputc::@1 +Adding NOP phi() at start of cscroll::@1 +Adding NOP phi() at start of cscroll::@2 +Adding NOP phi() at start of cscroll::@3 +Adding NOP phi() at start of cscroll::@4 + +FINAL CONTROL FLOW GRAPH + +void __start() +__start: scope:[__start] from + [0] phi() + to:__start::__init1 +__start::__init1: scope:[__start] from __start + [1] conio_cursor_x = 0 + [2] conio_cursor_y = 0 + [3] conio_line_text = DEFAULT_SCREEN + [4] conio_line_color = COLORRAM + to:__start::@1 +__start::@1: scope:[__start] from __start::__init1 + [5] phi() + [6] call main + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + [7] return + to:@return + +void world() +world: scope:[world] from + [8] phi() + [9] call cputs + to:world::@return +world::@return: scope:[world] from world + [10] return + to:@return + +void hello() +hello: scope:[hello] from + [11] phi() + [12] call cputs + to:hello::@return +hello::@return: scope:[hello] from hello + [13] return + to:@return + +void main() +main: scope:[main] from __start::@1 + [14] phi() + [15] call f1 + to:main::@1 +main::@1: scope:[main] from main + [16] phi() + [17] call f1 + to:main::@return +main::@return: scope:[main] from main::@1 + [18] return + to:@return + +void cputs(to_nomodify byte* cputs::s) +cputs: scope:[cputs] from hello world + [19] cputs::s#4 = phi( hello/hello::s, world/world::s ) + to:cputs::@1 +cputs::@1: scope:[cputs] from cputs cputs::@2 + [20] cputs::s#3 = phi( cputs/cputs::s#4, cputs::@2/cputs::s#0 ) + [21] cputs::c#1 = *cputs::s#3 + [22] cputs::s#0 = ++ cputs::s#3 + [23] if(0!=cputs::c#1) goto cputs::@2 + to:cputs::@return +cputs::@return: scope:[cputs] from cputs::@1 + [24] return + to:@return +cputs::@2: scope:[cputs] from cputs::@1 + [25] cputc::c#0 = cputs::c#1 + [26] call cputc + to:cputs::@1 + +void f1(void()* f1::fn) +f1: scope:[f1] from main main::@1 + [27] f1::fn#2 = phi( main/&hello, main::@1/&world ) + [28] call *f1::fn#2 + to:f1::@return +f1::@return: scope:[f1] from f1 + [29] return + to:@return + +void cputc(byte cputc::c) +cputc: scope:[cputc] from cputs::@2 + [30] if(cputc::c#0==' +') goto cputc::@1 + to:cputc::@2 +cputc::@2: scope:[cputc] from cputc + [31] conio_line_text[conio_cursor_x] = cputc::c#0 + [32] conio_line_color[conio_cursor_x] = LIGHT_BLUE + [33] conio_cursor_x = ++ conio_cursor_x + [34] if(conio_cursor_x!=$28) goto cputc::@return + to:cputc::@3 +cputc::@3: scope:[cputc] from cputc::@2 + [35] phi() + [36] call cputln + to:cputc::@return +cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@3 + [37] return + to:@return +cputc::@1: scope:[cputc] from cputc + [38] phi() + [39] call cputln + to:cputc::@return + +void cputln() +cputln: scope:[cputln] from cputc::@1 cputc::@3 + [40] conio_line_text = conio_line_text + $28 + [41] conio_line_color = conio_line_color + $28 + [42] conio_cursor_x = 0 + [43] conio_cursor_y = ++ conio_cursor_y + [44] call cscroll + to:cputln::@return +cputln::@return: scope:[cputln] from cputln + [45] return + to:@return + +void cscroll() +cscroll: scope:[cscroll] from cputln + [46] if(conio_cursor_y!=$19) goto cscroll::@return + to:cscroll::@1 +cscroll::@1: scope:[cscroll] from cscroll + [47] phi() + [48] call memcpy + to:cscroll::@2 +cscroll::@2: scope:[cscroll] from cscroll::@1 + [49] phi() + [50] call memcpy + to:cscroll::@3 +cscroll::@3: scope:[cscroll] from cscroll::@2 + [51] phi() + [52] call memset + to:cscroll::@4 +cscroll::@4: scope:[cscroll] from cscroll::@3 + [53] phi() + [54] call memset + to:cscroll::@5 +cscroll::@5: scope:[cscroll] from cscroll::@4 + [55] conio_line_text = conio_line_text - $28 + [56] conio_line_color = conio_line_color - $28 + [57] conio_cursor_y = -- conio_cursor_y + to:cscroll::@return +cscroll::@return: scope:[cscroll] from cscroll cscroll::@5 + [58] return + to:@return + +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +memcpy: scope:[memcpy] from cscroll::@1 cscroll::@2 + [59] memcpy::destination#2 = phi( cscroll::@1/(void*)DEFAULT_SCREEN, cscroll::@2/(void*)COLORRAM ) + [59] memcpy::source#2 = phi( cscroll::@1/(void*)DEFAULT_SCREEN+$28, cscroll::@2/(void*)COLORRAM+$28 ) + [60] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28 + [61] memcpy::src#4 = (byte*)memcpy::source#2 + [62] memcpy::dst#4 = (byte*)memcpy::destination#2 + to:memcpy::@1 +memcpy::@1: scope:[memcpy] from memcpy memcpy::@2 + [63] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 ) + [63] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 ) + [64] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 + to:memcpy::@return +memcpy::@return: scope:[memcpy] from memcpy::@1 + [65] return + to:@return +memcpy::@2: scope:[memcpy] from memcpy::@1 + [66] *memcpy::dst#2 = *memcpy::src#2 + [67] memcpy::dst#1 = ++ memcpy::dst#2 + [68] memcpy::src#1 = ++ memcpy::src#2 + to:memcpy::@1 + +void* memset(void* memset::str , byte memset::c , word memset::num) +memset: scope:[memset] from cscroll::@3 cscroll::@4 + [69] memset::c#4 = phi( cscroll::@3/' ', cscroll::@4/LIGHT_BLUE ) + [69] memset::str#3 = phi( cscroll::@3/(void*)DEFAULT_SCREEN+(word)$19*$28-$28, cscroll::@4/(void*)COLORRAM+(word)$19*$28-$28 ) + to:memset::@1 +memset::@1: scope:[memset] from memset + [70] memset::end#0 = (byte*)memset::str#3 + $28 + [71] memset::dst#4 = (byte*)memset::str#3 + to:memset::@2 +memset::@2: scope:[memset] from memset::@1 memset::@3 + [72] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 ) + [73] if(memset::dst#2!=memset::end#0) goto memset::@3 + to:memset::@return +memset::@return: scope:[memset] from memset::@2 + [74] return + to:@return +memset::@3: scope:[memset] from memset::@2 + [75] *memset::dst#2 = memset::c#4 + [76] memset::dst#1 = ++ memset::dst#2 + to:memset::@2 + + +VARIABLE REGISTER WEIGHTS +void __start() +byte conio_cursor_x loadstore 714.6666666666666 +byte conio_cursor_y loadstore 8421.236842105263 +byte* conio_line_color loadstore 5815.973684210527 +byte* conio_line_text loadstore 5815.973684210527 +void cputc(byte cputc::c) +byte cputc::c +byte cputc::c#0 1051.5 +void cputln() +void cputs(to_nomodify byte* cputs::s) +byte cputs::c +byte cputs::c#1 101.0 +to_nomodify byte* cputs::s +to_nomodify byte* cputs::s#0 50.5 +to_nomodify byte* cputs::s#3 157.0 +to_nomodify byte* cputs::s#4 11.0 +void cscroll() +void f1(void()* f1::fn) +void()* f1::fn +void()* f1::fn#2 +void hello() +void main() +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +void* memcpy::destination +void* memcpy::destination#2 +byte* memcpy::dst +byte* memcpy::dst#1 1.00000001E8 +byte* memcpy::dst#2 1.0033333466666667E8 +byte* memcpy::dst#4 2000002.0 +word memcpy::num +void* memcpy::return +void* memcpy::source +void* memcpy::source#2 +byte* memcpy::src +byte* memcpy::src#1 2.00000002E8 +byte* memcpy::src#2 1.0025000125E8 +byte* memcpy::src#4 1000001.0 +byte* memcpy::src_end +byte* memcpy::src_end#0 1.262500025E7 +void* memset(void* memset::str , byte memset::c , word memset::num) +byte memset::c +byte memset::c#4 1.428571442857143E7 +byte* memset::dst +byte* memset::dst#1 2.00000002E8 +byte* memset::dst#2 1.3366666833333334E8 +byte* memset::dst#4 2000002.0 +byte* memset::end +byte* memset::end#0 1.6833333666666668E7 +word memset::num +void* memset::return +void* memset::str +void* memset::str#3 +void world() + +Initial phi equivalence classes +[ cputs::s#3 cputs::s#4 cputs::s#0 ] +[ f1::fn#2 ] +[ memcpy::source#2 ] +[ memcpy::destination#2 ] +[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] +[ memset::str#3 ] +[ memset::c#4 ] +[ memset::dst#2 memset::dst#4 memset::dst#1 ] +Added variable conio_cursor_x to live range equivalence class [ conio_cursor_x ] +Added variable conio_cursor_y to live range equivalence class [ conio_cursor_y ] +Added variable conio_line_text to live range equivalence class [ conio_line_text ] +Added variable conio_line_color to live range equivalence class [ conio_line_color ] +Added variable cputs::c#1 to live range equivalence class [ cputs::c#1 ] +Added variable cputc::c#0 to live range equivalence class [ cputc::c#0 ] +Added variable memcpy::src_end#0 to live range equivalence class [ memcpy::src_end#0 ] +Added variable memset::end#0 to live range equivalence class [ memset::end#0 ] +Complete equivalence classes +[ cputs::s#3 cputs::s#4 cputs::s#0 ] +[ f1::fn#2 ] +[ memcpy::source#2 ] +[ memcpy::destination#2 ] +[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] +[ memset::str#3 ] +[ memset::c#4 ] +[ memset::dst#2 memset::dst#4 memset::dst#1 ] +[ conio_cursor_x ] +[ conio_cursor_y ] +[ conio_line_text ] +[ conio_line_color ] +[ cputs::c#1 ] +[ cputc::c#0 ] +[ memcpy::src_end#0 ] +[ memset::end#0 ] +Allocated zp[2]:2 [ cputs::s#3 cputs::s#4 cputs::s#0 ] +Allocated zp[2]:4 [ f1::fn#2 ] +Allocated zp[2]:6 [ memcpy::source#2 ] +Allocated zp[2]:8 [ memcpy::destination#2 ] +Allocated zp[2]:10 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +Allocated zp[2]:12 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] +Allocated zp[2]:14 [ memset::str#3 ] +Allocated zp[1]:16 [ memset::c#4 ] +Allocated zp[2]:17 [ memset::dst#2 memset::dst#4 memset::dst#1 ] +Allocated zp[1]:19 [ conio_cursor_x ] +Allocated zp[1]:20 [ conio_cursor_y ] +Allocated zp[2]:21 [ conio_line_text ] +Allocated zp[2]:23 [ conio_line_color ] +Allocated zp[1]:25 [ cputs::c#1 ] +Allocated zp[1]:26 [ cputc::c#0 ] +Allocated zp[2]:27 [ memcpy::src_end#0 ] +Allocated zp[2]:29 [ memset::end#0 ] +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [1] conio_cursor_x = 0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [2] conio_cursor_y = 0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [3] conio_line_text = DEFAULT_SCREEN [ ] ( [ ] { } ) always clobbers reg byte a +Statement [4] conio_line_color = COLORRAM [ ] ( [ ] { } ) always clobbers reg byte a +Statement [21] cputs::c#1 = *cputs::s#3 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#3 cputs::c#1 ] ( cputs:9 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#3 cputs::c#1 ] { } cputs:12 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#3 cputs::c#1 ] { } ) always clobbers reg byte a reg byte y +Statement [28] call *f1::fn#2 [ ] ( main:6::f1:15 [ ] { } main:6::f1:17 [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [31] conio_line_text[conio_cursor_x] = cputc::c#0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26 [ 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 [32] conio_line_color[conio_cursor_x] = LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26 [ 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 [34] if(conio_cursor_x!=$28) goto cputc::@return [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26 [ 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 +Statement [40] conio_line_text = conio_line_text + $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [41] conio_line_color = conio_line_color + $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [42] conio_cursor_x = 0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39 [ 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 +Statement [46] if(conio_cursor_y!=$19) goto cscroll::@return [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44 [ 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 +Statement [55] conio_line_text = conio_line_text - $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44 [ 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 +Statement [56] conio_line_color = conio_line_color - $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44 [ 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 +Statement [60] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [61] memcpy::src#4 = (byte*)memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [62] memcpy::dst#4 = (byte*)memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [64] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [66] *memcpy::dst#2 = *memcpy::src#2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Statement [70] memset::end#0 = (byte*)memset::str#3 + $28 [ memset::str#3 memset::c#4 memset::end#0 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:16 [ memset::c#4 ] +Statement [71] memset::dst#4 = (byte*)memset::str#3 [ memset::c#4 memset::end#0 memset::dst#4 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [73] if(memset::dst#2!=memset::end#0) goto memset::@3 [ memset::c#4 memset::end#0 memset::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [75] *memset::dst#2 = memset::c#4 [ memset::c#4 memset::end#0 memset::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp[1]:16 [ memset::c#4 ] +Statement [1] conio_cursor_x = 0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [2] conio_cursor_y = 0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [3] conio_line_text = DEFAULT_SCREEN [ ] ( [ ] { } ) always clobbers reg byte a +Statement [4] conio_line_color = COLORRAM [ ] ( [ ] { } ) always clobbers reg byte a +Statement [21] cputs::c#1 = *cputs::s#3 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#3 cputs::c#1 ] ( cputs:9 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#3 cputs::c#1 ] { } cputs:12 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#3 cputs::c#1 ] { } ) always clobbers reg byte a reg byte y +Statement [28] call *f1::fn#2 [ ] ( main:6::f1:15 [ ] { } main:6::f1:17 [ ] { } ) always clobbers reg byte a reg byte x reg byte y +Statement [31] conio_line_text[conio_cursor_x] = cputc::c#0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26 [ 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 [32] conio_line_color[conio_cursor_x] = LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26 [ 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 [34] if(conio_cursor_x!=$28) goto cputc::@return [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26 [ 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 +Statement [40] conio_line_text = conio_line_text + $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [41] conio_line_color = conio_line_color + $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [42] conio_cursor_x = 0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39 [ 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 +Statement [46] if(conio_cursor_y!=$19) goto cscroll::@return [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44 [ 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 +Statement [55] conio_line_text = conio_line_text - $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44 [ 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 +Statement [56] conio_line_color = conio_line_color - $28 [ conio_cursor_y conio_line_text conio_line_color ] ( cputs:9::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44 [ 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 +Statement [60] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [61] memcpy::src#4 = (byte*)memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [62] memcpy::dst#4 = (byte*)memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [64] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [66] *memcpy::dst#2 = *memcpy::src#2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memcpy:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Statement [70] memset::end#0 = (byte*)memset::str#3 + $28 [ memset::str#3 memset::c#4 memset::end#0 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [71] memset::dst#4 = (byte*)memset::str#3 [ memset::c#4 memset::end#0 memset::dst#4 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [73] if(memset::dst#2!=memset::end#0) goto memset::@3 [ memset::c#4 memset::end#0 memset::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [75] *memset::dst#2 = memset::c#4 [ memset::c#4 memset::end#0 memset::dst#2 ] ( cputs:9::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:52 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:36::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:9::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } cputs:12::cputc:26::cputln:39::cscroll:44::memset:54 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Potential registers zp[2]:2 [ cputs::s#3 cputs::s#4 cputs::s#0 ] : zp[2]:2 , +Potential registers zp[2]:4 [ f1::fn#2 ] : zp[2]:4 , +Potential registers zp[2]:6 [ memcpy::source#2 ] : zp[2]:6 , +Potential registers zp[2]:8 [ memcpy::destination#2 ] : zp[2]:8 , +Potential registers zp[2]:10 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] : zp[2]:10 , +Potential registers zp[2]:12 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp[2]:12 , +Potential registers zp[2]:14 [ memset::str#3 ] : zp[2]:14 , +Potential registers zp[1]:16 [ memset::c#4 ] : zp[1]:16 , reg byte x , +Potential registers zp[2]:17 [ memset::dst#2 memset::dst#4 memset::dst#1 ] : zp[2]:17 , +Potential registers zp[1]:19 [ conio_cursor_x ] : zp[1]:19 , +Potential registers zp[1]:20 [ conio_cursor_y ] : zp[1]:20 , +Potential registers zp[2]:21 [ conio_line_text ] : zp[2]:21 , +Potential registers zp[2]:23 [ conio_line_color ] : zp[2]:23 , +Potential registers zp[1]:25 [ cputs::c#1 ] : zp[1]:25 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:26 [ cputc::c#0 ] : zp[1]:26 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:27 [ memcpy::src_end#0 ] : zp[2]:27 , +Potential registers zp[2]:29 [ memset::end#0 ] : zp[2]:29 , + +REGISTER UPLIFT SCOPES +Uplift Scope [memcpy] 301,250,004.25: zp[2]:10 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 202,333,337.67: zp[2]:12 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 12,625,000.25: zp[2]:27 [ memcpy::src_end#0 ] 0: zp[2]:6 [ memcpy::source#2 ] 0: zp[2]:8 [ memcpy::destination#2 ] +Uplift Scope [memset] 335,666,672.33: zp[2]:17 [ memset::dst#2 memset::dst#4 memset::dst#1 ] 16,833,333.67: zp[2]:29 [ memset::end#0 ] 14,285,714.43: zp[1]:16 [ memset::c#4 ] 0: zp[2]:14 [ memset::str#3 ] +Uplift Scope [] 8,421.24: zp[1]:20 [ conio_cursor_y ] 5,815.97: zp[2]:21 [ conio_line_text ] 5,815.97: zp[2]:23 [ conio_line_color ] 714.67: zp[1]:19 [ conio_cursor_x ] +Uplift Scope [cputc] 1,051.5: zp[1]:26 [ cputc::c#0 ] +Uplift Scope [cputs] 218.5: zp[2]:2 [ cputs::s#3 cputs::s#4 cputs::s#0 ] 101: zp[1]:25 [ cputs::c#1 ] +Uplift Scope [RADIX] +Uplift Scope [MOS6526_CIA] +Uplift Scope [MOS6569_VICII] +Uplift Scope [MOS6581_SID] +Uplift Scope [cputln] +Uplift Scope [cscroll] +Uplift Scope [printf_format_number] +Uplift Scope [printf_buffer_number] +Uplift Scope [printf_format_string] +Uplift Scope [f1] 0: zp[2]:4 [ f1::fn#2 ] +Uplift Scope [hello] +Uplift Scope [world] +Uplift Scope [main] +Uplift Scope [__start] + +Uplifting [memcpy] best 12727 combination zp[2]:10 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp[2]:12 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp[2]:27 [ memcpy::src_end#0 ] zp[2]:6 [ memcpy::source#2 ] zp[2]:8 [ memcpy::destination#2 ] +Uplifting [memset] best 12621 combination zp[2]:17 [ memset::dst#2 memset::dst#4 memset::dst#1 ] zp[2]:29 [ memset::end#0 ] reg byte x [ memset::c#4 ] zp[2]:14 [ memset::str#3 ] +Uplifting [] best 12621 combination zp[1]:20 [ conio_cursor_y ] zp[2]:21 [ conio_line_text ] zp[2]:23 [ conio_line_color ] zp[1]:19 [ conio_cursor_x ] +Uplifting [cputc] best 12585 combination reg byte a [ cputc::c#0 ] +Uplifting [cputs] best 12495 combination zp[2]:2 [ cputs::s#3 cputs::s#4 cputs::s#0 ] reg byte a [ cputs::c#1 ] +Uplifting [RADIX] best 12495 combination +Uplifting [MOS6526_CIA] best 12495 combination +Uplifting [MOS6569_VICII] best 12495 combination +Uplifting [MOS6581_SID] best 12495 combination +Uplifting [cputln] best 12495 combination +Uplifting [cscroll] best 12495 combination +Uplifting [printf_format_number] best 12495 combination +Uplifting [printf_buffer_number] best 12495 combination +Uplifting [printf_format_string] best 12495 combination +Uplifting [f1] best 12495 combination zp[2]:4 [ f1::fn#2 ] +Uplifting [hello] best 12495 combination +Uplifting [world] best 12495 combination +Uplifting [main] best 12495 combination +Uplifting [__start] best 12495 combination +Attempting to uplift remaining variables inzp[1]:20 [ conio_cursor_y ] +Uplifting [] best 12495 combination zp[1]:20 [ conio_cursor_y ] +Attempting to uplift remaining variables inzp[1]:19 [ conio_cursor_x ] +Uplifting [] best 12495 combination zp[1]:19 [ conio_cursor_x ] +Coalescing zero page register [ zp[2]:6 [ memcpy::source#2 ] ] with [ zp[2]:10 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1 +Coalescing zero page register [ zp[2]:8 [ memcpy::destination#2 ] ] with [ zp[2]:12 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1 +Coalescing zero page register [ zp[2]:14 [ memset::str#3 ] ] with [ zp[2]:17 [ memset::dst#2 memset::dst#4 memset::dst#1 ] ] - score: 1 +Coalescing zero page register [ zp[2]:14 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 ] ] with [ zp[2]:6 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] +Coalescing zero page register [ zp[2]:29 [ memset::end#0 ] ] with [ zp[2]:8 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] +Allocated (was zp[2]:14) zp[2]:6 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +Allocated (was zp[1]:19) zp[1]:8 [ conio_cursor_x ] +Allocated (was zp[1]:20) zp[1]:9 [ conio_cursor_y ] +Allocated (was zp[2]:21) zp[2]:10 [ conio_line_text ] +Allocated (was zp[2]:23) zp[2]:12 [ conio_line_color ] +Allocated (was zp[2]:27) zp[2]:14 [ memcpy::src_end#0 ] +Allocated (was zp[2]:29) zp[2]:16 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Tests trouble passing a function pointer + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__start) +.pc = $80d "Program" + // Global Constants & labels + .const LIGHT_BLUE = $e + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $400 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = 8 + // The current cursor y-position + .label conio_cursor_y = 9 + // The current text cursor line start + .label conio_line_text = $a + // The current color cursor line start + .label conio_line_color = $c + // __start +__start: { + jmp __init1 + // __start::__init1 + __init1: + // [1] conio_cursor_x = 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // [2] conio_cursor_y = 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_y + // [3] conio_line_text = DEFAULT_SCREEN -- pbuz1=pbuc1 + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // [4] conio_line_color = COLORRAM -- pbuz1=pbuc1 + lda #COLORRAM + sta.z conio_line_color+1 + // [5] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + __b1_from___init1: + jmp __b1 + // __start::@1 + __b1: + // [6] call main + // [14] phi from __start::@1 to main [phi:__start::@1->main] + main_from___b1: + jsr main + jmp __breturn + // __start::@return + __breturn: + // [7] return + rts +} + // world +world: { + // [9] call cputs + // [19] phi from world to cputs [phi:world->cputs] + cputs_from_world: + // [19] phi cputs::s#4 = world::s [phi:world->cputs#0] -- pbuz1=pbuc1 + lda #s + sta.z cputs.s+1 + jsr cputs + jmp __breturn + // world::@return + __breturn: + // [10] return + rts + s: .text "world!" + .byte 0 +} + // hello +hello: { + // [12] call cputs + // [19] phi from hello to cputs [phi:hello->cputs] + cputs_from_hello: + // [19] phi cputs::s#4 = hello::s [phi:hello->cputs#0] -- pbuz1=pbuc1 + lda #s + sta.z cputs.s+1 + jsr cputs + jmp __breturn + // hello::@return + __breturn: + // [13] return + rts + s: .text "hello " + .byte 0 +} + // main +main: { + // [15] call f1 + // [27] phi from main to f1 [phi:main->f1] + f1_from_main: + // [27] phi f1::fn#2 = &hello [phi:main->f1#0] -- pprz1=pprc1 + lda #hello + sta.z f1.fn+1 + jsr f1 + // [16] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + jmp __b1 + // main::@1 + __b1: + // [17] call f1 + // [27] phi from main::@1 to f1 [phi:main::@1->f1] + f1_from___b1: + // [27] phi f1::fn#2 = &world [phi:main::@1->f1#0] -- pprz1=pprc1 + lda #world + sta.z f1.fn+1 + jsr f1 + jmp __breturn + // main::@return + __breturn: + // [18] return + rts +} + // cputs +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label s = 2 + // [20] phi from cputs cputs::@2 to cputs::@1 [phi:cputs/cputs::@2->cputs::@1] + __b1_from_cputs: + __b1_from___b2: + // [20] phi cputs::s#3 = cputs::s#4 [phi:cputs/cputs::@2->cputs::@1#0] -- register_copy + jmp __b1 + // cputs::@1 + __b1: + // [21] cputs::c#1 = *cputs::s#3 -- vbuaa=_deref_pbuz1 + ldy #0 + lda (s),y + // [22] cputs::s#0 = ++ cputs::s#3 -- pbuz1=_inc_pbuz1 + inc.z s + bne !+ + inc.z s+1 + !: + // [23] if(0!=cputs::c#1) goto cputs::@2 -- vbuc1_neq_vbuaa_then_la1 + cmp #0 + bne __b2 + jmp __breturn + // cputs::@return + __breturn: + // [24] return + rts + // cputs::@2 + __b2: + // [25] cputc::c#0 = cputs::c#1 + // [26] call cputc + jsr cputc + jmp __b1_from___b2 +} + // f1 +// f1(void()* zp(4) fn) +f1: { + .label fn = 4 + // [28] call *f1::fn#2 + jsr bi_fn + jmp __breturn + // f1::@return + __breturn: + // [29] return + rts + bi_fn: + jmp (fn) +} + // cputc +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte register(A) c) +cputc: { + // [30] if(cputc::c#0==' ') goto cputc::@1 -- vbuaa_eq_vbuc1_then_la1 + cmp #'\n' + beq __b1_from_cputc + jmp __b2 + // cputc::@2 + __b2: + // [31] conio_line_text[conio_cursor_x] = cputc::c#0 -- pbuz1_derefidx_vbuz2=vbuaa + ldy.z conio_cursor_x + sta (conio_line_text),y + // [32] conio_line_color[conio_cursor_x] = LIGHT_BLUE -- pbuz1_derefidx_vbuz2=vbuc1 + lda #LIGHT_BLUE + ldy.z conio_cursor_x + sta (conio_line_color),y + // [33] conio_cursor_x = ++ conio_cursor_x -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_x + // [34] if(conio_cursor_x!=$28) goto cputc::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$28 + cmp.z conio_cursor_x + bne __breturn + // [35] phi from cputc::@2 to cputc::@3 [phi:cputc::@2->cputc::@3] + __b3_from___b2: + jmp __b3 + // cputc::@3 + __b3: + // [36] call cputln + jsr cputln + jmp __breturn + // cputc::@return + __breturn: + // [37] return + rts + // [38] phi from cputc to cputc::@1 [phi:cputc->cputc::@1] + __b1_from_cputc: + jmp __b1 + // cputc::@1 + __b1: + // [39] call cputln + jsr cputln + jmp __breturn +} + // cputln +// Print a newline +cputln: { + // [40] conio_line_text = conio_line_text + $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // [41] conio_line_color = conio_line_color + $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // [42] conio_cursor_x = 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // [43] conio_cursor_y = ++ conio_cursor_y -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_y + // [44] call cscroll + jsr cscroll + jmp __breturn + // cputln::@return + __breturn: + // [45] return + rts +} + // cscroll +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // [46] if(conio_cursor_y!=$19) goto cscroll::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // [47] phi from cscroll to cscroll::@1 [phi:cscroll->cscroll::@1] + __b1_from_cscroll: + jmp __b1 + // cscroll::@1 + __b1: + // [48] call memcpy + // [59] phi from cscroll::@1 to memcpy [phi:cscroll::@1->memcpy] + memcpy_from___b1: + // [59] phi memcpy::destination#2 = (void*)DEFAULT_SCREEN [phi:cscroll::@1->memcpy#0] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + // [59] phi memcpy::source#2 = (void*)DEFAULT_SCREEN+$28 [phi:cscroll::@1->memcpy#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$28 + sta.z memcpy.source+1 + jsr memcpy + // [49] phi from cscroll::@1 to cscroll::@2 [phi:cscroll::@1->cscroll::@2] + __b2_from___b1: + jmp __b2 + // cscroll::@2 + __b2: + // [50] call memcpy + // [59] phi from cscroll::@2 to memcpy [phi:cscroll::@2->memcpy] + memcpy_from___b2: + // [59] phi memcpy::destination#2 = (void*)COLORRAM [phi:cscroll::@2->memcpy#0] -- pvoz1=pvoc1 + lda #COLORRAM + sta.z memcpy.destination+1 + // [59] phi memcpy::source#2 = (void*)COLORRAM+$28 [phi:cscroll::@2->memcpy#1] -- pvoz1=pvoc1 + lda #COLORRAM+$28 + sta.z memcpy.source+1 + jsr memcpy + // [51] phi from cscroll::@2 to cscroll::@3 [phi:cscroll::@2->cscroll::@3] + __b3_from___b2: + jmp __b3 + // cscroll::@3 + __b3: + // [52] call memset + // [69] phi from cscroll::@3 to memset [phi:cscroll::@3->memset] + memset_from___b3: + // [69] phi memset::c#4 = ' ' [phi:cscroll::@3->memset#0] -- vbuxx=vbuc1 + ldx #' ' + // [69] phi memset::str#3 = (void*)DEFAULT_SCREEN+(word)$19*$28-$28 [phi:cscroll::@3->memset#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$19*$28-$28 + sta.z memset.str+1 + jsr memset + // [53] phi from cscroll::@3 to cscroll::@4 [phi:cscroll::@3->cscroll::@4] + __b4_from___b3: + jmp __b4 + // cscroll::@4 + __b4: + // [54] call memset + // [69] phi from cscroll::@4 to memset [phi:cscroll::@4->memset] + memset_from___b4: + // [69] phi memset::c#4 = LIGHT_BLUE [phi:cscroll::@4->memset#0] -- vbuxx=vbuc1 + ldx #LIGHT_BLUE + // [69] phi memset::str#3 = (void*)COLORRAM+(word)$19*$28-$28 [phi:cscroll::@4->memset#1] -- pvoz1=pvoc1 + lda #COLORRAM+$19*$28-$28 + sta.z memset.str+1 + jsr memset + jmp __b5 + // cscroll::@5 + __b5: + // [55] conio_line_text = conio_line_text - $28 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_text + sbc #$28 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // [56] conio_line_color = conio_line_color - $28 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_color + sbc #$28 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // [57] conio_cursor_y = -- conio_cursor_y -- vbuz1=_dec_vbuz1 + dec.z conio_cursor_y + jmp __breturn + // cscroll::@return + __breturn: + // [58] return + rts +} + // memcpy +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp($10) destination, void* zp(6) source) +memcpy: { + .label src_end = $e + .label dst = $10 + .label src = 6 + .label source = 6 + .label destination = $10 + // [60] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28 -- pbuz1=pbuz2_plus_vwuc1 + clc + lda.z source + adc #<$19*$28-$28 + sta.z src_end + lda.z source+1 + adc #>$19*$28-$28 + sta.z src_end+1 + // [61] memcpy::src#4 = (byte*)memcpy::source#2 + // [62] memcpy::dst#4 = (byte*)memcpy::destination#2 + // [63] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1] + __b1_from_memcpy: + __b1_from___b2: + // [63] phi memcpy::dst#2 = memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy + // [63] phi memcpy::src#2 = memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy + jmp __b1 + // memcpy::@1 + __b1: + // [64] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + jmp __breturn + // memcpy::@return + __breturn: + // [65] return + rts + // memcpy::@2 + __b2: + // [66] *memcpy::dst#2 = *memcpy::src#2 -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (src),y + ldy #0 + sta (dst),y + // [67] memcpy::dst#1 = ++ memcpy::dst#2 -- pbuz1=_inc_pbuz1 + inc.z dst + bne !+ + inc.z dst+1 + !: + // [68] memcpy::src#1 = ++ memcpy::src#2 -- pbuz1=_inc_pbuz1 + inc.z src + bne !+ + inc.z src+1 + !: + jmp __b1_from___b2 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp(6) str, byte register(X) c) +memset: { + .label end = $10 + .label dst = 6 + .label str = 6 + jmp __b1 + // memset::@1 + __b1: + // [70] memset::end#0 = (byte*)memset::str#3 + $28 -- pbuz1=pbuz2_plus_vbuc1 + lda #$28 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + // [71] memset::dst#4 = (byte*)memset::str#3 + // [72] phi from memset::@1 memset::@3 to memset::@2 [phi:memset::@1/memset::@3->memset::@2] + __b2_from___b1: + __b2_from___b3: + // [72] phi memset::dst#2 = memset::dst#4 [phi:memset::@1/memset::@3->memset::@2#0] -- register_copy + jmp __b2 + // memset::@2 + __b2: + // [73] if(memset::dst#2!=memset::end#0) goto memset::@3 -- pbuz1_neq_pbuz2_then_la1 + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + jmp __breturn + // memset::@return + __breturn: + // [74] return + rts + // memset::@3 + __b3: + // [75] *memset::dst#2 = memset::c#4 -- _deref_pbuz1=vbuxx + txa + ldy #0 + sta (dst),y + // [76] memset::dst#1 = ++ memset::dst#2 -- pbuz1=_inc_pbuz1 + inc.z dst + bne !+ + inc.z dst+1 + !: + jmp __b2_from___b3 +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __init1 +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __b2 +Removing instruction jmp __b3 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __b2 +Removing instruction jmp __b3 +Removing instruction jmp __b4 +Removing instruction jmp __b5 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __b2 +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda #0 +Removing instruction ldy.z conio_cursor_x +Removing instruction ldy #0 +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Replacing label __b1_from___b2 with __b1 +Replacing label __b1_from_cputc with __b1 +Replacing label __b1_from___b2 with __b1 +Replacing label __b2_from___b3 with __b2 +Removing instruction __b1_from___init1: +Removing instruction main_from___b1: +Removing instruction __b1_from_main: +Removing instruction f1_from___b1: +Removing instruction __b1_from_cputs: +Removing instruction __b1_from___b2: +Removing instruction __b3_from___b2: +Removing instruction __b1_from_cputc: +Removing instruction __b1_from_cscroll: +Removing instruction memcpy_from___b1: +Removing instruction __b2_from___b1: +Removing instruction memcpy_from___b2: +Removing instruction __b3_from___b2: +Removing instruction memset_from___b3: +Removing instruction __b4_from___b3: +Removing instruction memset_from___b4: +Removing instruction __b1_from_memcpy: +Removing instruction __b1_from___b2: +Removing instruction __b2_from___b1: +Removing instruction __b2_from___b3: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __init1: +Removing instruction __b1: +Removing instruction __breturn: +Removing instruction cputs_from_world: +Removing instruction __breturn: +Removing instruction cputs_from_hello: +Removing instruction __breturn: +Removing instruction f1_from_main: +Removing instruction __b1: +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __b2: +Removing instruction __b3: +Removing instruction __breturn: +Removing instruction __b1: +Removing instruction __b2: +Removing instruction __b3: +Removing instruction __b4: +Removing instruction __b5: +Removing instruction __breturn: +Removing instruction __b1: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Replacing jump to rts with rts in jmp __breturn +Succesful ASM optimization Pass5DoubleJumpElimination + +FINAL SYMBOL TABLE +const nomodify byte* COLORRAM = (byte*) 55296 +const nomodify byte* DEFAULT_SCREEN = (byte*) 1024 +const nomodify byte LIGHT_BLUE = $e +const byte RADIX::BINARY = 2 +const byte RADIX::DECIMAL = $a +const byte RADIX::HEXADECIMAL = $10 +const byte RADIX::OCTAL = 8 +void __start() +byte conio_cursor_x loadstore zp[1]:8 714.6666666666666 +byte conio_cursor_y loadstore zp[1]:9 8421.236842105263 +byte* conio_line_color loadstore zp[2]:12 5815.973684210527 +byte* conio_line_text loadstore zp[2]:10 5815.973684210527 +void cputc(byte cputc::c) +byte cputc::c +byte cputc::c#0 reg byte a 1051.5 +void cputln() +void cputs(to_nomodify byte* cputs::s) +byte cputs::c +byte cputs::c#1 reg byte a 101.0 +to_nomodify byte* cputs::s +to_nomodify byte* cputs::s#0 s zp[2]:2 50.5 +to_nomodify byte* cputs::s#3 s zp[2]:2 157.0 +to_nomodify byte* cputs::s#4 s zp[2]:2 11.0 +void cscroll() +void f1(void()* f1::fn) +void()* f1::fn +void()* f1::fn#2 fn zp[2]:4 +void hello() +const byte* hello::s[7] = "hello " +void main() +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +void* memcpy::destination +void* memcpy::destination#2 destination zp[2]:16 +byte* memcpy::dst +byte* memcpy::dst#1 dst zp[2]:16 1.00000001E8 +byte* memcpy::dst#2 dst zp[2]:16 1.0033333466666667E8 +byte* memcpy::dst#4 dst zp[2]:16 2000002.0 +word memcpy::num +void* memcpy::return +void* memcpy::source +void* memcpy::source#2 source zp[2]:6 +byte* memcpy::src +byte* memcpy::src#1 src zp[2]:6 2.00000002E8 +byte* memcpy::src#2 src zp[2]:6 1.0025000125E8 +byte* memcpy::src#4 src zp[2]:6 1000001.0 +byte* memcpy::src_end +byte* memcpy::src_end#0 src_end zp[2]:14 1.262500025E7 +void* memset(void* memset::str , byte memset::c , word memset::num) +byte memset::c +byte memset::c#4 reg byte x 1.428571442857143E7 +byte* memset::dst +byte* memset::dst#1 dst zp[2]:6 2.00000002E8 +byte* memset::dst#2 dst zp[2]:6 1.3366666833333334E8 +byte* memset::dst#4 dst zp[2]:6 2000002.0 +byte* memset::end +byte* memset::end#0 end zp[2]:16 1.6833333666666668E7 +word memset::num +void* memset::return +void* memset::str +void* memset::str#3 str zp[2]:6 +void world() +const byte* world::s[7] = "world!" + +zp[2]:2 [ cputs::s#3 cputs::s#4 cputs::s#0 ] +zp[2]:4 [ f1::fn#2 ] +zp[2]:6 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +reg byte x [ memset::c#4 ] +zp[1]:8 [ conio_cursor_x ] +zp[1]:9 [ conio_cursor_y ] +zp[2]:10 [ conio_line_text ] +zp[2]:12 [ conio_line_color ] +reg byte a [ cputs::c#1 ] +reg byte a [ cputc::c#0 ] +zp[2]:14 [ memcpy::src_end#0 ] +zp[2]:16 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] + + +FINAL ASSEMBLER +Score: 10883 + + // File Comments +// Tests trouble passing a function pointer + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__start) +.pc = $80d "Program" + // Global Constants & labels + .const LIGHT_BLUE = $e + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $400 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = 8 + // The current cursor y-position + .label conio_cursor_y = 9 + // The current text cursor line start + .label conio_line_text = $a + // The current color cursor line start + .label conio_line_color = $c + // __start +__start: { + // __start::__init1 + // conio_cursor_x = 0 + // [1] conio_cursor_x = 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y = 0 + // [2] conio_cursor_y = 0 -- vbuz1=vbuc1 + sta.z conio_cursor_y + // conio_line_text = CONIO_SCREEN_TEXT + // [3] conio_line_text = DEFAULT_SCREEN -- pbuz1=pbuc1 + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // conio_line_color = CONIO_SCREEN_COLORS + // [4] conio_line_color = COLORRAM -- pbuz1=pbuc1 + lda #COLORRAM + sta.z conio_line_color+1 + // [5] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + // __start::@1 + // [6] call main + // [14] phi from __start::@1 to main [phi:__start::@1->main] + jsr main + // __start::@return + // [7] return + rts +} + // world +world: { + // printf("world!") + // [9] call cputs + // [19] phi from world to cputs [phi:world->cputs] + // [19] phi cputs::s#4 = world::s [phi:world->cputs#0] -- pbuz1=pbuc1 + lda #s + sta.z cputs.s+1 + jsr cputs + // world::@return + // } + // [10] return + rts + s: .text "world!" + .byte 0 +} + // hello +hello: { + // printf("hello ") + // [12] call cputs + // [19] phi from hello to cputs [phi:hello->cputs] + // [19] phi cputs::s#4 = hello::s [phi:hello->cputs#0] -- pbuz1=pbuc1 + lda #s + sta.z cputs.s+1 + jsr cputs + // hello::@return + // } + // [13] return + rts + s: .text "hello " + .byte 0 +} + // main +main: { + // f1(&hello) + // [15] call f1 + // [27] phi from main to f1 [phi:main->f1] + // [27] phi f1::fn#2 = &hello [phi:main->f1#0] -- pprz1=pprc1 + lda #hello + sta.z f1.fn+1 + jsr f1 + // [16] phi from main to main::@1 [phi:main->main::@1] + // main::@1 + // f1(&world) + // [17] call f1 + // [27] phi from main::@1 to f1 [phi:main::@1->f1] + // [27] phi f1::fn#2 = &world [phi:main::@1->f1#0] -- pprz1=pprc1 + lda #world + sta.z f1.fn+1 + jsr f1 + // main::@return + // } + // [18] return + rts +} + // cputs +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label s = 2 + // [20] phi from cputs cputs::@2 to cputs::@1 [phi:cputs/cputs::@2->cputs::@1] + // [20] phi cputs::s#3 = cputs::s#4 [phi:cputs/cputs::@2->cputs::@1#0] -- register_copy + // cputs::@1 + __b1: + // while(c=*s++) + // [21] cputs::c#1 = *cputs::s#3 -- vbuaa=_deref_pbuz1 + ldy #0 + lda (s),y + // [22] cputs::s#0 = ++ cputs::s#3 -- pbuz1=_inc_pbuz1 + inc.z s + bne !+ + inc.z s+1 + !: + // [23] if(0!=cputs::c#1) goto cputs::@2 -- vbuc1_neq_vbuaa_then_la1 + cmp #0 + bne __b2 + // cputs::@return + // } + // [24] return + rts + // cputs::@2 + __b2: + // cputc(c) + // [25] cputc::c#0 = cputs::c#1 + // [26] call cputc + jsr cputc + jmp __b1 +} + // f1 +// f1(void()* zp(4) fn) +f1: { + .label fn = 4 + // (*fn)() + // [28] call *f1::fn#2 + jsr bi_fn + // f1::@return + // } + // [29] return + rts + bi_fn: + jmp (fn) +} + // cputc +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte register(A) c) +cputc: { + // if(c=='\n') + // [30] if(cputc::c#0==' ') goto cputc::@1 -- vbuaa_eq_vbuc1_then_la1 + cmp #'\n' + beq __b1 + // cputc::@2 + // conio_line_text[conio_cursor_x] = c + // [31] conio_line_text[conio_cursor_x] = cputc::c#0 -- pbuz1_derefidx_vbuz2=vbuaa + ldy.z conio_cursor_x + sta (conio_line_text),y + // conio_line_color[conio_cursor_x] = conio_textcolor + // [32] conio_line_color[conio_cursor_x] = LIGHT_BLUE -- pbuz1_derefidx_vbuz2=vbuc1 + lda #LIGHT_BLUE + sta (conio_line_color),y + // if(++conio_cursor_x==CONIO_WIDTH) + // [33] conio_cursor_x = ++ conio_cursor_x -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_x + // [34] if(conio_cursor_x!=$28) goto cputc::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$28 + cmp.z conio_cursor_x + bne __breturn + // [35] phi from cputc::@2 to cputc::@3 [phi:cputc::@2->cputc::@3] + // cputc::@3 + // cputln() + // [36] call cputln + jsr cputln + // cputc::@return + __breturn: + // } + // [37] return + rts + // [38] phi from cputc to cputc::@1 [phi:cputc->cputc::@1] + // cputc::@1 + __b1: + // cputln() + // [39] call cputln + jsr cputln + rts +} + // cputln +// Print a newline +cputln: { + // conio_line_text += CONIO_WIDTH + // [40] conio_line_text = conio_line_text + $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // conio_line_color += CONIO_WIDTH + // [41] conio_line_color = conio_line_color + $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // conio_cursor_x = 0 + // [42] conio_cursor_x = 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y++; + // [43] conio_cursor_y = ++ conio_cursor_y -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_y + // cscroll() + // [44] call cscroll + jsr cscroll + // cputln::@return + // } + // [45] return + rts +} + // cscroll +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // if(conio_cursor_y==CONIO_HEIGHT) + // [46] if(conio_cursor_y!=$19) goto cscroll::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // [47] phi from cscroll to cscroll::@1 [phi:cscroll->cscroll::@1] + // cscroll::@1 + // memcpy(CONIO_SCREEN_TEXT, CONIO_SCREEN_TEXT+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + // [48] call memcpy + // [59] phi from cscroll::@1 to memcpy [phi:cscroll::@1->memcpy] + // [59] phi memcpy::destination#2 = (void*)DEFAULT_SCREEN [phi:cscroll::@1->memcpy#0] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + // [59] phi memcpy::source#2 = (void*)DEFAULT_SCREEN+$28 [phi:cscroll::@1->memcpy#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$28 + sta.z memcpy.source+1 + jsr memcpy + // [49] phi from cscroll::@1 to cscroll::@2 [phi:cscroll::@1->cscroll::@2] + // cscroll::@2 + // memcpy(CONIO_SCREEN_COLORS, CONIO_SCREEN_COLORS+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + // [50] call memcpy + // [59] phi from cscroll::@2 to memcpy [phi:cscroll::@2->memcpy] + // [59] phi memcpy::destination#2 = (void*)COLORRAM [phi:cscroll::@2->memcpy#0] -- pvoz1=pvoc1 + lda #COLORRAM + sta.z memcpy.destination+1 + // [59] phi memcpy::source#2 = (void*)COLORRAM+$28 [phi:cscroll::@2->memcpy#1] -- pvoz1=pvoc1 + lda #COLORRAM+$28 + sta.z memcpy.source+1 + jsr memcpy + // [51] phi from cscroll::@2 to cscroll::@3 [phi:cscroll::@2->cscroll::@3] + // cscroll::@3 + // memset(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH) + // [52] call memset + // [69] phi from cscroll::@3 to memset [phi:cscroll::@3->memset] + // [69] phi memset::c#4 = ' ' [phi:cscroll::@3->memset#0] -- vbuxx=vbuc1 + ldx #' ' + // [69] phi memset::str#3 = (void*)DEFAULT_SCREEN+(word)$19*$28-$28 [phi:cscroll::@3->memset#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$19*$28-$28 + sta.z memset.str+1 + jsr memset + // [53] phi from cscroll::@3 to cscroll::@4 [phi:cscroll::@3->cscroll::@4] + // cscroll::@4 + // memset(CONIO_SCREEN_COLORS+CONIO_BYTES-CONIO_WIDTH, conio_textcolor, CONIO_WIDTH) + // [54] call memset + // [69] phi from cscroll::@4 to memset [phi:cscroll::@4->memset] + // [69] phi memset::c#4 = LIGHT_BLUE [phi:cscroll::@4->memset#0] -- vbuxx=vbuc1 + ldx #LIGHT_BLUE + // [69] phi memset::str#3 = (void*)COLORRAM+(word)$19*$28-$28 [phi:cscroll::@4->memset#1] -- pvoz1=pvoc1 + lda #COLORRAM+$19*$28-$28 + sta.z memset.str+1 + jsr memset + // cscroll::@5 + // conio_line_text -= CONIO_WIDTH + // [55] conio_line_text = conio_line_text - $28 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_text + sbc #$28 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // conio_line_color -= CONIO_WIDTH + // [56] conio_line_color = conio_line_color - $28 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_color + sbc #$28 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // conio_cursor_y--; + // [57] conio_cursor_y = -- conio_cursor_y -- vbuz1=_dec_vbuz1 + dec.z conio_cursor_y + // cscroll::@return + __breturn: + // } + // [58] return + rts +} + // memcpy +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp($10) destination, void* zp(6) source) +memcpy: { + .label src_end = $e + .label dst = $10 + .label src = 6 + .label source = 6 + .label destination = $10 + // src_end = (char*)source+num + // [60] memcpy::src_end#0 = (byte*)memcpy::source#2 + (word)$19*$28-$28 -- pbuz1=pbuz2_plus_vwuc1 + clc + lda.z source + adc #<$19*$28-$28 + sta.z src_end + lda.z source+1 + adc #>$19*$28-$28 + sta.z src_end+1 + // [61] memcpy::src#4 = (byte*)memcpy::source#2 + // [62] memcpy::dst#4 = (byte*)memcpy::destination#2 + // [63] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1] + // [63] phi memcpy::dst#2 = memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy + // [63] phi memcpy::src#2 = memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy + // memcpy::@1 + __b1: + // while(src!=src_end) + // [64] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + // memcpy::@return + // } + // [65] return + rts + // memcpy::@2 + __b2: + // *dst++ = *src++ + // [66] *memcpy::dst#2 = *memcpy::src#2 -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (src),y + sta (dst),y + // *dst++ = *src++; + // [67] memcpy::dst#1 = ++ memcpy::dst#2 -- pbuz1=_inc_pbuz1 + inc.z dst + bne !+ + inc.z dst+1 + !: + // [68] memcpy::src#1 = ++ memcpy::src#2 -- pbuz1=_inc_pbuz1 + inc.z src + bne !+ + inc.z src+1 + !: + jmp __b1 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp(6) str, byte register(X) c) +memset: { + .label end = $10 + .label dst = 6 + .label str = 6 + // memset::@1 + // end = (char*)str + num + // [70] memset::end#0 = (byte*)memset::str#3 + $28 -- pbuz1=pbuz2_plus_vbuc1 + lda #$28 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + // [71] memset::dst#4 = (byte*)memset::str#3 + // [72] phi from memset::@1 memset::@3 to memset::@2 [phi:memset::@1/memset::@3->memset::@2] + // [72] phi memset::dst#2 = memset::dst#4 [phi:memset::@1/memset::@3->memset::@2#0] -- register_copy + // memset::@2 + __b2: + // for(char* dst = str; dst!=end; dst++) + // [73] if(memset::dst#2!=memset::end#0) goto memset::@3 -- pbuz1_neq_pbuz2_then_la1 + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + // memset::@return + // } + // [74] return + rts + // memset::@3 + __b3: + // *dst = c + // [75] *memset::dst#2 = memset::c#4 -- _deref_pbuz1=vbuxx + txa + ldy #0 + sta (dst),y + // for(char* dst = str; dst!=end; dst++) + // [76] memset::dst#1 = ++ memset::dst#2 -- pbuz1=_inc_pbuz1 + inc.z dst + bne !+ + inc.z dst+1 + !: + jmp __b2 +} + // File Data + diff --git a/src/test/ref/function-pointer-noarg-call-14.sym b/src/test/ref/function-pointer-noarg-call-14.sym new file mode 100644 index 000000000..44a99d1bb --- /dev/null +++ b/src/test/ref/function-pointer-noarg-call-14.sym @@ -0,0 +1,75 @@ +const nomodify byte* COLORRAM = (byte*) 55296 +const nomodify byte* DEFAULT_SCREEN = (byte*) 1024 +const nomodify byte LIGHT_BLUE = $e +const byte RADIX::BINARY = 2 +const byte RADIX::DECIMAL = $a +const byte RADIX::HEXADECIMAL = $10 +const byte RADIX::OCTAL = 8 +void __start() +byte conio_cursor_x loadstore zp[1]:8 714.6666666666666 +byte conio_cursor_y loadstore zp[1]:9 8421.236842105263 +byte* conio_line_color loadstore zp[2]:12 5815.973684210527 +byte* conio_line_text loadstore zp[2]:10 5815.973684210527 +void cputc(byte cputc::c) +byte cputc::c +byte cputc::c#0 reg byte a 1051.5 +void cputln() +void cputs(to_nomodify byte* cputs::s) +byte cputs::c +byte cputs::c#1 reg byte a 101.0 +to_nomodify byte* cputs::s +to_nomodify byte* cputs::s#0 s zp[2]:2 50.5 +to_nomodify byte* cputs::s#3 s zp[2]:2 157.0 +to_nomodify byte* cputs::s#4 s zp[2]:2 11.0 +void cscroll() +void f1(void()* f1::fn) +void()* f1::fn +void()* f1::fn#2 fn zp[2]:4 +void hello() +const byte* hello::s[7] = "hello " +void main() +void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num) +void* memcpy::destination +void* memcpy::destination#2 destination zp[2]:16 +byte* memcpy::dst +byte* memcpy::dst#1 dst zp[2]:16 1.00000001E8 +byte* memcpy::dst#2 dst zp[2]:16 1.0033333466666667E8 +byte* memcpy::dst#4 dst zp[2]:16 2000002.0 +word memcpy::num +void* memcpy::return +void* memcpy::source +void* memcpy::source#2 source zp[2]:6 +byte* memcpy::src +byte* memcpy::src#1 src zp[2]:6 2.00000002E8 +byte* memcpy::src#2 src zp[2]:6 1.0025000125E8 +byte* memcpy::src#4 src zp[2]:6 1000001.0 +byte* memcpy::src_end +byte* memcpy::src_end#0 src_end zp[2]:14 1.262500025E7 +void* memset(void* memset::str , byte memset::c , word memset::num) +byte memset::c +byte memset::c#4 reg byte x 1.428571442857143E7 +byte* memset::dst +byte* memset::dst#1 dst zp[2]:6 2.00000002E8 +byte* memset::dst#2 dst zp[2]:6 1.3366666833333334E8 +byte* memset::dst#4 dst zp[2]:6 2000002.0 +byte* memset::end +byte* memset::end#0 end zp[2]:16 1.6833333666666668E7 +word memset::num +void* memset::return +void* memset::str +void* memset::str#3 str zp[2]:6 +void world() +const byte* world::s[7] = "world!" + +zp[2]:2 [ cputs::s#3 cputs::s#4 cputs::s#0 ] +zp[2]:4 [ f1::fn#2 ] +zp[2]:6 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +reg byte x [ memset::c#4 ] +zp[1]:8 [ conio_cursor_x ] +zp[1]:9 [ conio_cursor_y ] +zp[2]:10 [ conio_line_text ] +zp[2]:12 [ conio_line_color ] +reg byte a [ cputs::c#1 ] +reg byte a [ cputc::c#0 ] +zp[2]:14 [ memcpy::src_end#0 ] +zp[2]:16 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] diff --git a/src/test/ref/function-pointer-problem-1.asm b/src/test/ref/function-pointer-problem-1.asm new file mode 100644 index 000000000..7d2e8705f --- /dev/null +++ b/src/test/ref/function-pointer-problem-1.asm @@ -0,0 +1,34 @@ +// The following casuses an exception in pass 2 +// https://gitlab.com/camelot/kickc/-/issues/561 +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label r = $8000 +fn1: { + // *r = 1 + lda #1 + sta r + // } + rts +} +main: { + // enableDLI(&fn1) + jsr enableDLI + // } + rts +} +// enableDLI(void* dliptr) +enableDLI: { + .label dliptr = fn1 + // asm + lda #dliptr + sta dlivec+1 + jmp !+ + dlivec: + .byte 0, 0 + !: + // } + rts +} diff --git a/src/test/ref/function-pointer-problem-1.cfg b/src/test/ref/function-pointer-problem-1.cfg new file mode 100644 index 000000000..5a950194e --- /dev/null +++ b/src/test/ref/function-pointer-problem-1.cfg @@ -0,0 +1,25 @@ + +void fn1() +fn1: scope:[fn1] from + [0] *r = 1 + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + [1] return + to:@return + +void main() +main: scope:[main] from + [2] phi() + [3] call enableDLI + to:main::@return +main::@return: scope:[main] from main + [4] return + to:@return + +void enableDLI(const void* enableDLI::dliptr) +enableDLI: scope:[enableDLI] from main + asm { lda#dliptr stadlivec+1 jmp!+ dlivec: .byte0,0 !: } + to:enableDLI::@return +enableDLI::@return: scope:[enableDLI] from enableDLI + [6] return + to:@return diff --git a/src/test/ref/function-pointer-problem-1.log b/src/test/ref/function-pointer-problem-1.log new file mode 100644 index 000000000..e87775ea7 --- /dev/null +++ b/src/test/ref/function-pointer-problem-1.log @@ -0,0 +1,257 @@ +Resolved forward reference fn1 to void fn1() +Inlined call call __init + +CONTROL FLOW GRAPH SSA + +void main() +main: scope:[main] from __start::@1 + enableDLI::dliptr = (void*)&fn1 + call enableDLI + to:main::@1 +main::@1: scope:[main] from main + to:main::@return +main::@return: scope:[main] from main::@1 + return + to:@return + +void fn1() +fn1: scope:[fn1] from + *r = 1 + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + return + to:@return + +void enableDLI(void* enableDLI::dliptr) +enableDLI: scope:[enableDLI] from main + asm { lda#dliptr stadlivec+1 jmp!+ dlivec: .byte0,0 !: } + to:enableDLI::@return +enableDLI::@return: scope:[enableDLI] from enableDLI + return + to:@return + +void __start() +__start: scope:[__start] from + to:__start::__init1 +__start::__init1: scope:[__start] from __start + to:__start::@1 +__start::@1: scope:[__start] from __start::__init1 + call main + to:__start::@2 +__start::@2: scope:[__start] from __start::@1 + to:__start::@return +__start::@return: scope:[__start] from __start::@2 + return + to:@return + +SYMBOL TABLE SSA +void __start() +void enableDLI(void* enableDLI::dliptr) +void* enableDLI::dliptr loadstore +void fn1() +void main() +const to_nomodify byte* r = (byte*)$8000 + +Adding number conversion cast (unumber) 1 in *r = 1 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast *r = (unumber)1 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 32768 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant enableDLI::dliptr = (void*)&fn1 +Successful SSA optimization Pass2ConstantIdentification +Removing unused procedure __start +Removing unused procedure block __start +Removing unused procedure block __start::__init1 +Removing unused procedure block __start::@1 +Removing unused procedure block __start::@2 +Removing unused procedure block __start::@return +Successful SSA optimization PassNEliminateEmptyStart +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +CALL GRAPH +Calls in [main] to enableDLI:3 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block label main::@1 +Adding NOP phi() at start of main + +FINAL CONTROL FLOW GRAPH + +void fn1() +fn1: scope:[fn1] from + [0] *r = 1 + to:fn1::@return +fn1::@return: scope:[fn1] from fn1 + [1] return + to:@return + +void main() +main: scope:[main] from + [2] phi() + [3] call enableDLI + to:main::@return +main::@return: scope:[main] from main + [4] return + to:@return + +void enableDLI(const void* enableDLI::dliptr) +enableDLI: scope:[enableDLI] from main + asm { lda#dliptr stadlivec+1 jmp!+ dlivec: .byte0,0 !: } + to:enableDLI::@return +enableDLI::@return: scope:[enableDLI] from enableDLI + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +void enableDLI(const void* enableDLI::dliptr) +void fn1() +void main() + +Initial phi equivalence classes +Complete equivalence classes +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] *r = 1 [ ] ( [ ] { } ) always clobbers reg byte a +Statement asm { lda#dliptr stadlivec+1 jmp!+ dlivec: .byte0,0 !: } always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [fn1] +Uplift Scope [enableDLI] +Uplift Scope [] + +Uplifting [main] best 54 combination +Uplifting [fn1] best 54 combination +Uplifting [enableDLI] best 54 combination +Uplifting [] best 54 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// The following casuses an exception in pass 2 +// https://gitlab.com/camelot/kickc/-/issues/561 + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label r = $8000 + // fn1 +fn1: { + // [0] *r = 1 -- _deref_pbuc1=vbuc2 + lda #1 + sta r + jmp __breturn + // fn1::@return + __breturn: + // [1] return + rts +} + // main +main: { + // [3] call enableDLI + jsr enableDLI + jmp __breturn + // main::@return + __breturn: + // [4] return + rts +} + // enableDLI +// enableDLI(void* dliptr) +enableDLI: { + .label dliptr = fn1 + // asm { lda#dliptr stadlivec+1 jmp!+ dlivec: .byte0,0 !: } + lda #dliptr + sta dlivec+1 + jmp !+ + dlivec: + .byte 0, 0 + !: + jmp __breturn + // enableDLI::@return + __breturn: + // [6] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +void enableDLI(const void* enableDLI::dliptr) +const void* enableDLI::dliptr = (void*)&fn1 +void fn1() +void main() +const to_nomodify byte* r = (byte*) 32768 + + + +FINAL ASSEMBLER +Score: 45 + + // File Comments +// The following casuses an exception in pass 2 +// https://gitlab.com/camelot/kickc/-/issues/561 + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label r = $8000 + // fn1 +fn1: { + // *r = 1 + // [0] *r = 1 -- _deref_pbuc1=vbuc2 + lda #1 + sta r + // fn1::@return + // } + // [1] return + rts +} + // main +main: { + // enableDLI(&fn1) + // [3] call enableDLI + jsr enableDLI + // main::@return + // } + // [4] return + rts +} + // enableDLI +// enableDLI(void* dliptr) +enableDLI: { + .label dliptr = fn1 + // asm + // asm { lda#dliptr stadlivec+1 jmp!+ dlivec: .byte0,0 !: } + lda #dliptr + sta dlivec+1 + jmp !+ + dlivec: + .byte 0, 0 + !: + // enableDLI::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/function-pointer-problem-1.sym b/src/test/ref/function-pointer-problem-1.sym new file mode 100644 index 000000000..8b1edd4fe --- /dev/null +++ b/src/test/ref/function-pointer-problem-1.sym @@ -0,0 +1,6 @@ +void enableDLI(const void* enableDLI::dliptr) +const void* enableDLI::dliptr = (void*)&fn1 +void fn1() +void main() +const to_nomodify byte* r = (byte*) 32768 +