diff --git a/src/test/ref/procedure-callingconvention-stack-11.asm b/src/test/ref/procedure-callingconvention-stack-11.asm new file mode 100644 index 000000000..578d774ca --- /dev/null +++ b/src/test/ref/procedure-callingconvention-stack-11.asm @@ -0,0 +1,178 @@ +// Test a procedure with calling convention stack +// Returning and passing struct of struct values +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const STACK_BASE = $103 + .label idx = 2 +__bbegin: + // idx = 0 + lda #0 + sta.z idx + jsr main + rts +// print(byte register(Y) v_p1_x, byte zp(3) v_p1_y, byte zp(4) v_p2_x, byte register(X) v_p2_y) +print: { + .const OFFSET_STACK_V_P1_X = 3 + .const OFFSET_STACK_V_P1_Y = 2 + .const OFFSET_STACK_V_P2_X = 1 + .const OFFSET_STACK_V_P2_Y = 0 + .label v_p1_y = 3 + .label v_p2_x = 4 + // } + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_X,x + tay + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_Y,x + sta.z v_p1_y + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_X,x + sta.z v_p2_x + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_Y,x + tax + // SCREEN[idx++] = v.p1.x + tya + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = v.p1.x; + inc.z idx + // SCREEN[idx++] = v.p1.y + lda.z v_p1_y + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = v.p1.y; + inc.z idx + // SCREEN[idx++] = v.p2.x + lda.z v_p2_x + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = v.p2.x; + inc.z idx + // SCREEN[idx++] = v.p2.y + ldy.z idx + txa + sta SCREEN,y + // SCREEN[idx++] = v.p2.y; + inc.z idx + // SCREEN[idx++] = ' ' + lda #' ' + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = ' '; + inc.z idx + // } + rts +} +// get(byte register(Y) i) +get: { + .const OFFSET_STACK_I = 0 + .label __0 = 3 + .label __2 = 4 + .label v = $10 + .label return_p2_x = 6 + .label return_p2_y = 7 + tsx + lda STACK_BASE+OFFSET_STACK_I,x + tay + // i/2 + tya + lsr + sta.z __0 + // i+1 + tya + tax + inx + // i*2 + tya + asl + sta.z __2 + // v = { {i, i/2}, {i+1, i*2} } + sty.z v + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + stx v+OFFSET_STRUCT_VECTOR_P2 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // return v; + ldx.z v + ldy v+OFFSET_STRUCT_POINT_Y + lda v+OFFSET_STRUCT_VECTOR_P2 + sta.z return_p2_x + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + sta.z return_p2_y + // } + txa + tsx + sta STACK_BASE+0,x + tya + tsx + sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x + lda.z return_p2_x + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x + lda.z return_p2_y + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x + rts +} +main: { + .label i = 5 + .label v = $c + .label __1_p2_x = 6 + .label __1_p2_y = 7 + // i=0 + lda #0 + sta.z i + __b1: + // for(char i=0;i<5;i++) + lda.z i + cmp #5 + bcc __b2 + // } + rts + __b2: + // get(i) + lda.z i + pha + pha + pha + pha + jsr get + pla + tay + pla + tax + pla + sta.z __1_p2_x + pla + sta.z __1_p2_y + // v = get(i) + sty.z v + stx v+OFFSET_STRUCT_POINT_Y + lda.z __1_p2_x + sta v+OFFSET_STRUCT_VECTOR_P2 + lda.z __1_p2_y + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // print(v) + tya + pha + txa + pha + lda v+OFFSET_STRUCT_VECTOR_P2 + pha + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + pha + jsr print + tsx + txa + axs #-4 + txs + // for(char i=0;i<5;i++) + inc.z i + jmp __b1 +} diff --git a/src/test/ref/procedure-callingconvention-stack-11.cfg b/src/test/ref/procedure-callingconvention-stack-11.cfg new file mode 100644 index 000000000..629d6ba32 --- /dev/null +++ b/src/test/ref/procedure-callingconvention-stack-11.cfg @@ -0,0 +1,84 @@ +@begin: scope:[] from + [0] (byte) idx ← (byte) 0 + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] callexecute main + to:@end +@end: scope:[] from @1 + [3] phi() + +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +print: scope:[print] from + [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) + [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) + [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) + [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) + [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 + [9] (byte) idx ← ++ (byte) idx + [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 + [11] (byte) idx ← ++ (byte) idx + [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 + [13] (byte) idx ← ++ (byte) idx + [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 + [15] (byte) idx ← ++ (byte) idx + [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' + [17] (byte) idx ← ++ (byte) idx + to:print::@return +print::@return: scope:[print] from print + [18] return + to:@return + +__stackcall (struct Vector()) get((byte) get::i) +get: scope:[get] from + [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) + [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 + [21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1 + [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 + [23] *((byte*)(struct Point*)&(struct Vector) get::v) ← (byte) get::i#0 + [24] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 + [25] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) get::$1 + [26] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$2 + [27] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v) + [28] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) + [29] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) + [30] (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) + to:get::@return +get::@return: scope:[get] from get + [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 + [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 + [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 + [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 + [35] return + to:@return + +__stackcall (void()) main() +main: scope:[main] from + [36] (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@2 + [37] if((byte) main::i<(byte) 5) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@1 + [38] return + to:@return +main::@2: scope:[main] from main::@1 + [39] stackpush(byte) ← (byte) main::i + sideeffect stackpushbytes((number) 3) + [41] callexecute get + [42] (byte~) main::$1_p1_x ← stackpull(byte) + [43] (byte~) main::$1_p1_y ← stackpull(byte) + [44] (byte~) main::$1_p2_x ← stackpull(byte) + [45] (byte~) main::$1_p2_y ← stackpull(byte) + [46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x + [47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y + [48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x + [49] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y + [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) + [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) + [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) + [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) + [54] callexecute print + sideeffect stackpullbytes((number) 4) + [56] (byte) main::i ← ++ (byte) main::i + to:main::@1 diff --git a/src/test/ref/procedure-callingconvention-stack-11.log b/src/test/ref/procedure-callingconvention-stack-11.log new file mode 100644 index 000000000..178d42d09 --- /dev/null +++ b/src/test/ref/procedure-callingconvention-stack-11.log @@ -0,0 +1,1537 @@ +Created struct value member variable (struct Point~) main::$1_p1 +Created struct value member variable (struct Point~) main::$1_p2 +Converted struct value to member variables (struct Vector~) main::$1 +Created struct value member variable (struct Point) get::return_p1 +Created struct value member variable (struct Point) get::return_p2 +Converted struct value to member variables (struct Vector) get::return +Created struct value member variable (struct Point) print::v_p1 +Created struct value member variable (struct Point) print::v_p2 +Converted struct value to member variables (struct Vector) print::v +Created struct value member variable (byte~) main::$1_p1_x +Created struct value member variable (byte~) main::$1_p1_y +Converted struct value to member variables (struct Point~) main::$1_p1 +Created struct value member variable (byte~) main::$1_p2_x +Created struct value member variable (byte~) main::$1_p2_y +Converted struct value to member variables (struct Point~) main::$1_p2 +Created struct value member variable (byte) get::return_p1_x +Created struct value member variable (byte) get::return_p1_y +Converted struct value to member variables (struct Point) get::return_p1 +Created struct value member variable (byte) get::return_p2_x +Created struct value member variable (byte) get::return_p2_y +Converted struct value to member variables (struct Point) get::return_p2 +Created struct value member variable (byte) print::v_p1_x +Created struct value member variable (byte) print::v_p1_y +Converted struct value to member variables (struct Point) print::v_p1 +Created struct value member variable (byte) print::v_p2_x +Created struct value member variable (byte) print::v_p2_y +Converted struct value to member variables (struct Point) print::v_p2 +Converted procedure struct value parameter to member unwinding __stackcall (void()) print((struct Point) print::v_p1 , (struct Point) print::v_p2) +Converted procedure call LValue to member unwinding { { (byte~) main::$1_p1_x, (byte~) main::$1_p1_y }, { (byte~) main::$1_p2_x, (byte~) main::$1_p2_y } } ← call get (byte) main::i +Unwinding value copy (struct Vector) main::v ← (struct Vector~) main::$1 +Unwinding value copy (struct Vector) main::v ← (struct Vector~) main::$1 +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_p1_x +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y +Unwinding value copy (struct Vector) main::v ← (struct Vector~) main::$1 +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_p2_x +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y +Converted procedure struct value parameter to member unwinding in call (void~) main::$2 ← call print *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1) *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) +Unwinding value copy (struct Vector) get::v ← (struct Vector){ (struct Point){ (byte) get::i, (number~) get::$0 }, (struct Point){ (number~) get::$1, (number~) get::$2 } } +Unwinding value copy (struct Vector) get::v ← (struct Vector){ (struct Point){ (byte) get::i, (number~) get::$0 }, (struct Point){ (number~) get::$1, (number~) get::$2 } } +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number~) get::$0 +Unwinding value copy (struct Vector) get::v ← (struct Vector){ (struct Point){ (byte) get::i, (number~) get::$0 }, (struct Point){ (number~) get::$1, (number~) get::$2 } } +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (number~) get::$1 +Adding value simple copy *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (number~) get::$2 +Unwinding value copy (struct Vector) get::return ← (struct Vector) get::v +Unwinding value copy (struct Vector) get::return ← (struct Vector) get::v +Adding value simple copy (byte) get::return_p1_x ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) +Adding value simple copy (byte) get::return_p1_y ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) +Unwinding value copy (struct Vector) get::return ← (struct Vector) get::v +Adding value simple copy (byte) get::return_p2_x ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) +Adding value simple copy (byte) get::return_p2_y ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) +Converted procedure struct return value to member unwinding return { { (byte) get::return_p1_x, (byte) get::return_p1_y }, { (byte) get::return_p2_x, (byte) get::return_p2_y } } +Unwinding value copy (struct Vector) print::v ← param((struct Vector) print::v) +Unwinding value copy (struct Vector) print::v ← param((struct Vector) print::v) +Adding value simple copy (byte) print::v_p1_x ← param((byte) print::v_p1_x) +Adding value simple copy (byte) print::v_p1_y ← param((byte) print::v_p1_y) +Unwinding value copy (struct Vector) print::v ← param((struct Vector) print::v) +Adding value simple copy (byte) print::v_p2_x ← param((byte) print::v_p2_x) +Adding value simple copy (byte) print::v_p2_y ← param((byte) print::v_p2_y) +Replacing struct member reference (struct Vector) print::v.p1.x with member unwinding reference (byte) print::v_p1_x +Replacing struct member reference (struct Vector) print::v.p1.y with member unwinding reference (byte) print::v_p1_y +Replacing struct member reference (struct Vector) print::v.p2.x with member unwinding reference (byte) print::v_p2_x +Replacing struct member reference (struct Vector) print::v.p2.y with member unwinding reference (byte) print::v_p2_y +Converted procedure struct value parameter to member unwinding __stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +Converted procedure struct value parameter to member unwinding in call (void~) main::$2 ← call print *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) +Eliminating unused variable with no statement (struct Vector~) main::$1 +Eliminating unused variable with no statement (struct Point~) main::$1_p1 +Eliminating unused variable with no statement (struct Point~) main::$1_p2 +Culled Empty Block (label) main::@4 +Culled Empty Block (label) main::@3 +Culled Empty Block (label) main::@5 +Culled Empty Block (label) main::@6 +Culled Empty Block (label) @1 +Culled Empty Block (label) get::@1 +Culled Empty Block (label) @2 +Calling convention STACK_CALL adding prepare/execute/finalize for { { (byte~) main::$1_p1_x, (byte~) main::$1_p1_y }, { (byte~) main::$1_p2_x, (byte~) main::$1_p2_y } } ← call get (byte) main::i +Calling convention STACK_CALL adding prepare/execute/finalize for call print *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) +Calling convention STACK_CALL adding prepare/execute/finalize for call main +Calling convention STACK_CALL replacing param((byte) get::i) with stackidx(byte,(const byte) get::OFFSET_STACK_I) +Calling convention STACK_CALL replacing param((byte) print::v_p1_x) with stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) +Calling convention STACK_CALL replacing param((byte) print::v_p1_y) with stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) +Calling convention STACK_CALL replacing param((byte) print::v_p2_x) with stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) +Calling convention STACK_CALL replacing param((byte) print::v_p2_y) with stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) +Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) ← get::return_p1_x +Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) ← get::return_p1_y +Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) ← get::return_p2_x +Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) ← get::return_p2_y +Calling convention STACK_CALL adding stack pull main::$1_p1_x ← stackpull(byte) +Calling convention STACK_CALL adding stack pull main::$1_p1_y ← stackpull(byte) +Calling convention STACK_CALL adding stack pull main::$1_p2_x ← stackpull(byte) +Calling convention STACK_CALL adding stack pull main::$1_p2_y ← stackpull(byte) +Calling convention STACK_CALL adding stack push stackpush(byte) ← main::i +Calling convention STACK_CALL adding stack push stackpush(byte) ← *((byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_X) +Calling convention STACK_CALL adding stack push stackpush(byte) ← *((byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P1+OFFSET_STRUCT_POINT_Y) +Calling convention STACK_CALL adding stack push stackpush(byte) ← *((byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_X) +Calling convention STACK_CALL adding stack push stackpush(byte) ← *((byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y) + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte) idx ← (byte) 0 + to:@3 + +__stackcall (void()) main() +main: scope:[main] from + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@2 + (bool~) main::$0 ← (byte) main::i < (number) 5 + if((bool~) main::$0) goto main::@2 + to:main::@return +main::@2: scope:[main] from main::@1 + stackpush(byte) ← (byte) main::i + sideeffect stackpushbytes((number) 3) + callexecute get + (byte~) main::$1_p1_x ← stackpull(byte) + (byte~) main::$1_p1_y ← stackpull(byte) + (byte~) main::$1_p2_x ← stackpull(byte) + (byte~) main::$1_p2_y ← stackpull(byte) + *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_p1_x + *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y + *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_p2_x + *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y + (struct Vector) main::v ← struct-unwound {*((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y), *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y)} + stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) + stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) + stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) + stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) + callexecute print + sideeffect stackpullbytes((number) 4) + (byte) main::i ← ++ (byte) main::i + to:main::@1 +main::@return: scope:[main] from main::@1 + return + to:@return + +__stackcall (struct Vector()) get((byte) get::i) +get: scope:[get] from + (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) + (number~) get::$0 ← (byte) get::i#0 / (number) 2 + (number~) get::$1 ← (byte) get::i#0 + (number) 1 + (number~) get::$2 ← (byte) get::i#0 * (number) 2 + *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i#0 + *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number~) get::$0 + *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (number~) get::$1 + *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (number~) get::$2 + (struct Vector) get::v ← struct-unwound {*((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y), *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y)} + (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) + (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) + (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) + (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) + (struct Vector) get::return#0 ← struct-unwound {(byte) get::return_p1_x#0, (byte) get::return_p1_y#0, (byte) get::return_p2_x#0, (byte) get::return_p2_y#0} + to:get::@return +get::@return: scope:[get] from get + (byte) get::return_p2_y#1 ← phi( get/(byte) get::return_p2_y#0 ) + (byte) get::return_p2_x#1 ← phi( get/(byte) get::return_p2_x#0 ) + (byte) get::return_p1_y#1 ← phi( get/(byte) get::return_p1_y#0 ) + (byte) get::return_p1_x#1 ← phi( get/(byte) get::return_p1_x#0 ) + stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_p1_x#1 + stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#1 + stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_p2_x#1 + stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#1 + return + to:@return + +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +print: scope:[print] from + (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) + (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) + (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) + (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) + *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 + (byte) idx ← ++ (byte) idx + *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 + (byte) idx ← ++ (byte) idx + *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 + (byte) idx ← ++ (byte) idx + *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 + (byte) idx ← ++ (byte) idx + *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' + (byte) idx ← ++ (byte) idx + to:print::@return +print::@return: scope:[print] from print + return + to:@return +@3: scope:[] from @begin + callexecute main + to:@end +@end: scope:[] from @3 + +SYMBOL TABLE SSA +(label) @3 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_X = (byte) 0 +(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1 +(const byte) OFFSET_STRUCT_VECTOR_P1 = (byte) 0 +(const byte) OFFSET_STRUCT_VECTOR_P2 = (byte) 2 +(byte) Point::x loadstore +(byte) Point::y loadstore +(const byte*) SCREEN = (byte*)(number) $400 +(const word) STACK_BASE = (word) $103 +(struct Point) Vector::p1 loadstore +(struct Point) Vector::p2 loadstore +__stackcall (struct Vector()) get((byte) get::i) +(number~) get::$0 +(number~) get::$1 +(number~) get::$2 +(label) get::@return +(const byte) get::OFFSET_STACK_I = (byte) 0 +(const byte) get::OFFSET_STACK_RETURN = (byte) 0 +(byte) get::i +(byte) get::i#0 +(struct Vector) get::return +(struct Vector) get::return#0 +(struct Point) get::return_p1 +(byte) get::return_p1_x +(byte) get::return_p1_x#0 +(byte) get::return_p1_x#1 +(byte) get::return_p1_y +(byte) get::return_p1_y#0 +(byte) get::return_p1_y#1 +(struct Point) get::return_p2 +(byte) get::return_p2_x +(byte) get::return_p2_x#0 +(byte) get::return_p2_x#1 +(byte) get::return_p2_y +(byte) get::return_p2_y#0 +(byte) get::return_p2_y#1 +(struct Vector) get::v loadstore +(byte) idx loadstore +__stackcall (void()) main() +(bool~) main::$0 +(byte~) main::$1_p1_x +(byte~) main::$1_p1_y +(byte~) main::$1_p2_x +(byte~) main::$1_p2_y +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::i loadstore +(struct Vector) main::v loadstore +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +(label) print::@return +(const byte) print::OFFSET_STACK_V_P1_X = (byte) 3 +(const byte) print::OFFSET_STACK_V_P1_Y = (byte) 2 +(const byte) print::OFFSET_STACK_V_P2_X = (byte) 1 +(const byte) print::OFFSET_STACK_V_P2_Y = (byte) 0 +(struct Point) print::v_p1 +(byte) print::v_p1_x +(byte) print::v_p1_x#0 +(byte) print::v_p1_y +(byte) print::v_p1_y#0 +(struct Point) print::v_p2 +(byte) print::v_p2_x +(byte) print::v_p2_x#0 +(byte) print::v_p2_y +(byte) print::v_p2_y#0 + +Adding number conversion cast (unumber) 5 in (bool~) main::$0 ← (byte) main::i < (number) 5 +Adding number conversion cast (unumber) 2 in (number~) get::$0 ← (byte) get::i#0 / (number) 2 +Adding number conversion cast (unumber) get::$0 in (number~) get::$0 ← (byte) get::i#0 / (unumber)(number) 2 +Adding number conversion cast (unumber) 1 in (number~) get::$1 ← (byte) get::i#0 + (number) 1 +Adding number conversion cast (unumber) get::$1 in (number~) get::$1 ← (byte) get::i#0 + (unumber)(number) 1 +Adding number conversion cast (unumber) 2 in (number~) get::$2 ← (byte) get::i#0 * (number) 2 +Adding number conversion cast (unumber) get::$2 in (number~) get::$2 ← (byte) get::i#0 * (unumber)(number) 2 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 5 +Simplifying constant integer cast 2 +Simplifying constant integer cast 1 +Simplifying constant integer cast 2 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 5 +Finalized unsigned number type (byte) 2 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 2 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to byte in (unumber~) get::$0 ← (byte) get::i#0 / (byte) 2 +Inferred type updated to byte in (unumber~) get::$1 ← (byte) get::i#0 + (byte) 1 +Inferred type updated to byte in (unumber~) get::$2 ← (byte) get::i#0 * (byte) 2 +Alias (byte) get::return_p1_x#0 = (byte) get::return_p1_x#1 +Alias (byte) get::return_p1_y#0 = (byte) get::return_p1_y#1 +Alias (byte) get::return_p2_x#0 = (byte) get::return_p2_x#1 +Alias (byte) get::return_p2_y#0 = (byte) get::return_p2_y#1 +Successful SSA optimization Pass2AliasElimination +Simple Condition (bool~) main::$0 [3] if((byte) main::i<(byte) 5) goto main::@2 +Successful SSA optimization Pass2ConditionalJumpSimplification +Removing C-classic struct-unwound assignment [15] (struct Vector) main::v ← struct-unwound {*((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y), *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y)} +Removing C-classic struct-unwound assignment [32] (struct Vector) get::v ← struct-unwound {*((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y), *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y)} +Simplifying constant evaluating to zero (const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X in [38] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_p1_x#0 +Simplifying constant evaluating to zero (const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P1 in [39] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 +Successful SSA optimization PassNSimplifyConstantZero +Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P1 in [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_p1_x +Simplifying expression containing zero (struct Point*)&main::v in [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1) ← (byte~) main::$1_p1_x +Simplifying expression containing zero (struct Point*)&main::v in [12] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y +Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P2 in [13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_p2_x +Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P1 in [16] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero (struct Point*)&main::v in [16] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1) +Simplifying expression containing zero (struct Point*)&main::v in [17] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) +Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P2 in [18] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero (byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1 in [28] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i#0 +Simplifying expression containing zero (struct Point*)&get::v in [28] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1) ← (byte) get::i#0 +Simplifying expression containing zero (struct Point*)&get::v in [29] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 +Simplifying expression containing zero (byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2 in [30] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) get::$1 +Simplifying expression containing zero (byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P1 in [33] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero (struct Point*)&get::v in [33] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1) +Simplifying expression containing zero (struct Point*)&get::v in [34] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P1+(const byte) OFFSET_STRUCT_POINT_Y) +Simplifying expression containing zero (byte*)(struct Point*)&get::v+OFFSET_STRUCT_VECTOR_P2 in [35] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero OFFSET_STRUCT_POINT_Y in [39] stackidx(byte,(byte) 0+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 +Simplifying expression containing zero get::OFFSET_STACK_RETURN+OFFSET_STRUCT_VECTOR_P2 in [40] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_p2_x#0 +Simplifying expression containing zero OFFSET_STRUCT_VECTOR_P2 in [41] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Simplifying expression containing zero OFFSET_STRUCT_VECTOR_P2 in [40] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused variable (struct Vector) get::return#0 and assignment [34] (struct Vector) get::return#0 ← struct-unwound {(byte) get::return_p1_x#0, (byte) get::return_p1_y#0, (byte) get::return_p2_x#0, (byte) get::return_p2_y#0} +Eliminating unused constant (const byte) get::OFFSET_STACK_RETURN +Eliminating unused constant (const byte) OFFSET_STRUCT_VECTOR_P1 +Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X +Successful SSA optimization PassNEliminateUnusedVars +Rewriting division to use shift [23] (byte~) get::$0 ← (byte) get::i#0 / (byte) 2 +Rewriting multiplication to use shift [25] (byte~) get::$2 ← (byte) get::i#0 * (byte) 2 +Successful SSA optimization Pass2MultiplyToShiftRewriting +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 +Calls in [main] to get:41 print:54 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Renumbering block @3 to @1 +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] (byte) idx ← (byte) 0 + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] callexecute main + to:@end +@end: scope:[] from @1 + [3] phi() + +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +print: scope:[print] from + [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) + [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) + [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) + [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) + [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 + [9] (byte) idx ← ++ (byte) idx + [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 + [11] (byte) idx ← ++ (byte) idx + [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 + [13] (byte) idx ← ++ (byte) idx + [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 + [15] (byte) idx ← ++ (byte) idx + [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' + [17] (byte) idx ← ++ (byte) idx + to:print::@return +print::@return: scope:[print] from print + [18] return + to:@return + +__stackcall (struct Vector()) get((byte) get::i) +get: scope:[get] from + [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) + [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 + [21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1 + [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 + [23] *((byte*)(struct Point*)&(struct Vector) get::v) ← (byte) get::i#0 + [24] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 + [25] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) get::$1 + [26] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$2 + [27] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v) + [28] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) + [29] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) + [30] (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) + to:get::@return +get::@return: scope:[get] from get + [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 + [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 + [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 + [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 + [35] return + to:@return + +__stackcall (void()) main() +main: scope:[main] from + [36] (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@2 + [37] if((byte) main::i<(byte) 5) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@1 + [38] return + to:@return +main::@2: scope:[main] from main::@1 + [39] stackpush(byte) ← (byte) main::i + sideeffect stackpushbytes((number) 3) + [41] callexecute get + [42] (byte~) main::$1_p1_x ← stackpull(byte) + [43] (byte~) main::$1_p1_y ← stackpull(byte) + [44] (byte~) main::$1_p2_x ← stackpull(byte) + [45] (byte~) main::$1_p2_y ← stackpull(byte) + [46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x + [47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y + [48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x + [49] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y + [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) + [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) + [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) + [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) + [54] callexecute print + sideeffect stackpullbytes((number) 4) + [56] (byte) main::i ← ++ (byte) main::i + to:main::@1 + +null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 main::@1 in scope print +null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 main::@1 in scope get + +VARIABLE REGISTER WEIGHTS +(byte) Point::x loadstore +(byte) Point::y loadstore +(struct Point) Vector::p1 loadstore +(struct Point) Vector::p2 loadstore +__stackcall (struct Vector()) get((byte) get::i) +(byte~) get::$0 1.0 +(byte~) get::$1 1.0 +(byte~) get::$2 1.0 +(byte) get::i +(byte) get::i#0 2.5 +(struct Vector) get::return +(struct Point) get::return_p1 +(byte) get::return_p1_x +(byte) get::return_p1_x#0 1.0 +(byte) get::return_p1_y +(byte) get::return_p1_y#0 1.0 +(struct Point) get::return_p2 +(byte) get::return_p2_x +(byte) get::return_p2_x#0 1.0 +(byte) get::return_p2_y +(byte) get::return_p2_y#0 1.0 +(struct Vector) get::v loadstore +(byte) idx loadstore 0.8648648648648649 +__stackcall (void()) main() +(byte~) main::$1_p1_x 5.5 +(byte~) main::$1_p1_y 5.5 +(byte~) main::$1_p2_x 5.5 +(byte~) main::$1_p2_y 5.5 +(byte) main::i loadstore 2.3000000000000003 +(struct Vector) main::v loadstore +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +(struct Point) print::v_p1 +(byte) print::v_p1_x +(byte) print::v_p1_x#0 1.0 +(byte) print::v_p1_y +(byte) print::v_p1_y#0 0.8 +(struct Point) print::v_p2 +(byte) print::v_p2_x +(byte) print::v_p2_x#0 0.6666666666666666 +(byte) print::v_p2_y +(byte) print::v_p2_y#0 0.5714285714285714 + +Initial phi equivalence classes +Added variable idx to live range equivalence class [ idx ] +Added variable print::v_p1_x#0 to live range equivalence class [ print::v_p1_x#0 ] +Added variable print::v_p1_y#0 to live range equivalence class [ print::v_p1_y#0 ] +Added variable print::v_p2_x#0 to live range equivalence class [ print::v_p2_x#0 ] +Added variable print::v_p2_y#0 to live range equivalence class [ print::v_p2_y#0 ] +Added variable get::i#0 to live range equivalence class [ get::i#0 ] +Added variable get::$0 to live range equivalence class [ get::$0 ] +Added variable get::$1 to live range equivalence class [ get::$1 ] +Added variable get::$2 to live range equivalence class [ get::$2 ] +Added variable get::return_p1_x#0 to live range equivalence class [ get::return_p1_x#0 ] +Added variable get::return_p1_y#0 to live range equivalence class [ get::return_p1_y#0 ] +Added variable get::return_p2_x#0 to live range equivalence class [ get::return_p2_x#0 ] +Added variable get::return_p2_y#0 to live range equivalence class [ get::return_p2_y#0 ] +Added variable main::i to live range equivalence class [ main::i ] +Added variable main::$1_p1_x to live range equivalence class [ main::$1_p1_x ] +Added variable main::$1_p1_y to live range equivalence class [ main::$1_p1_y ] +Added variable main::$1_p2_x to live range equivalence class [ main::$1_p2_x ] +Added variable main::$1_p2_y to live range equivalence class [ main::$1_p2_y ] +Added variable Vector::p1 to live range equivalence class [ Vector::p1 ] +Added variable Vector::p2 to live range equivalence class [ Vector::p2 ] +Added variable main::v to live range equivalence class [ main::v ] +Added variable get::v to live range equivalence class [ get::v ] +Complete equivalence classes +[ idx ] +[ print::v_p1_x#0 ] +[ print::v_p1_y#0 ] +[ print::v_p2_x#0 ] +[ print::v_p2_y#0 ] +[ get::i#0 ] +[ get::$0 ] +[ get::$1 ] +[ get::$2 ] +[ get::return_p1_x#0 ] +[ get::return_p1_y#0 ] +[ get::return_p2_x#0 ] +[ get::return_p2_y#0 ] +[ main::i ] +[ main::$1_p1_x ] +[ main::$1_p1_y ] +[ main::$1_p2_x ] +[ main::$1_p2_y ] +[ Vector::p1 ] +[ Vector::p2 ] +[ main::v ] +[ get::v ] +Allocated zp[1]:2 [ idx ] +Allocated zp[1]:3 [ print::v_p1_x#0 ] +Allocated zp[1]:4 [ print::v_p1_y#0 ] +Allocated zp[1]:5 [ print::v_p2_x#0 ] +Allocated zp[1]:6 [ print::v_p2_y#0 ] +Allocated zp[1]:7 [ get::i#0 ] +Allocated zp[1]:8 [ get::$0 ] +Allocated zp[1]:9 [ get::$1 ] +Allocated zp[1]:10 [ get::$2 ] +Allocated zp[1]:11 [ get::return_p1_x#0 ] +Allocated zp[1]:12 [ get::return_p1_y#0 ] +Allocated zp[1]:13 [ get::return_p2_x#0 ] +Allocated zp[1]:14 [ get::return_p2_y#0 ] +Allocated zp[1]:15 [ main::i ] +Allocated zp[1]:16 [ main::$1_p1_x ] +Allocated zp[1]:17 [ main::$1_p1_y ] +Allocated zp[1]:18 [ main::$1_p2_x ] +Allocated zp[1]:19 [ main::$1_p2_y ] +Allocated zp[2]:20 [ Vector::p1 ] +Allocated zp[2]:22 [ Vector::p2 ] +Allocated zp[4]:24 [ main::v ] +Allocated zp[4]:28 [ get::v ] + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Test a procedure with calling convention stack +// Returning and passing struct of struct values + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const STACK_BASE = $103 + .label idx = 2 + // @begin +__bbegin: + // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] callexecute main -- jsr + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // print +// print(byte zp(3) v_p1_x, byte zp(4) v_p1_y, byte zp(5) v_p2_x, byte zp(6) v_p2_y) +print: { + .const OFFSET_STACK_V_P1_X = 3 + .const OFFSET_STACK_V_P1_Y = 2 + .const OFFSET_STACK_V_P2_X = 1 + .const OFFSET_STACK_V_P2_Y = 0 + .label v_p1_x = 3 + .label v_p1_y = 4 + .label v_p2_x = 5 + .label v_p2_y = 6 + // [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_X,x + sta.z v_p1_x + // [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_Y,x + sta.z v_p1_y + // [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_X,x + sta.z v_p2_x + // [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_Y,x + sta.z v_p2_y + // [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p1_x + ldy.z idx + sta SCREEN,y + // [9] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p1_y + ldy.z idx + sta SCREEN,y + // [11] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p2_x + ldy.z idx + sta SCREEN,y + // [13] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p2_y + ldy.z idx + sta SCREEN,y + // [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #' ' + ldy.z idx + sta SCREEN,y + // [17] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + jmp __breturn + // print::@return + __breturn: + // [18] return + rts +} + // get +// get(byte zp(7) i) +get: { + .const OFFSET_STACK_I = 0 + .label __0 = 8 + .label __1 = 9 + .label __2 = $a + .label v = $1c + .label i = 7 + .label return_p1_x = $b + .label return_p1_y = $c + .label return_p2_x = $d + .label return_p2_y = $e + // [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_I,x + sta.z i + // [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuz1=vbuz2_ror_1 + lda.z i + lsr + sta.z __0 + // [21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1 -- vbuz1=vbuz2_plus_1 + ldy.z i + iny + sty.z __1 + // [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda.z i + asl + sta.z __2 + // [23] *((byte*)(struct Point*)&(struct Vector) get::v) ← (byte) get::i#0 -- _deref_pbuc1=vbuz1 + lda.z i + sta.z v + // [24] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuz1 + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + // [25] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) get::$1 -- _deref_pbuc1=vbuz1 + lda.z __1 + sta v+OFFSET_STRUCT_VECTOR_P2 + // [26] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$2 -- _deref_pbuc1=vbuz1 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // [27] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v) -- vbuz1=_deref_pbuc1 + lda.z v + sta.z return_p1_x + // [28] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_POINT_Y + sta.z return_p1_y + // [29] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2 + sta.z return_p2_x + // [30] (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + sta.z return_p2_y + jmp __breturn + // get::@return + __breturn: + // [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p1_x + tsx + sta STACK_BASE+0,x + // [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p1_y + tsx + sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x + // [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p2_x + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x + // [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p2_y + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x + // [35] return + rts +} + // main +main: { + .label i = $f + .label v = $18 + .label __1_p1_x = $10 + .label __1_p1_y = $11 + .label __1_p2_x = $12 + .label __1_p2_y = $13 + // [36] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z i + jmp __b1 + // main::@1 + __b1: + // [37] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z i + cmp #5 + bcc __b2 + jmp __breturn + // main::@return + __breturn: + // [38] return + rts + // main::@2 + __b2: + // [39] stackpush(byte) ← (byte) main::i -- _stackpushbyte_=vbuz1 + lda.z i + pha + // sideeffect stackpushbytes((number) 3) -- _stackpushbyte_3 + pha + pha + pha + // [41] callexecute get -- jsr + jsr get + // [42] (byte~) main::$1_p1_x ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p1_x + // [43] (byte~) main::$1_p1_y ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p1_y + // [44] (byte~) main::$1_p2_x ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p2_x + // [45] (byte~) main::$1_p2_y ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p2_y + // [46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x -- _deref_pbuc1=vbuz1 + lda.z __1_p1_x + sta.z v + // [47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y -- _deref_pbuc1=vbuz1 + lda.z __1_p1_y + sta v+OFFSET_STRUCT_POINT_Y + // [48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x -- _deref_pbuc1=vbuz1 + lda.z __1_p2_x + sta v+OFFSET_STRUCT_VECTOR_P2 + // [49] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y -- _deref_pbuc1=vbuz1 + lda.z __1_p2_y + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _stackpushbyte_=_deref_pbuc1 + lda.z v + pha + // [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_POINT_Y + pha + // [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2 + pha + // [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + pha + // [54] callexecute print -- jsr + jsr print + // sideeffect stackpullbytes((number) 4) -- _stackpullbyte_4 + tsx + txa + axs #-4 + txs + // [56] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + inc.z i + jmp __b1 +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] (byte) idx ← (byte) 0 [ idx get::v main::v ] ( [ idx get::v main::v ] ) always clobbers reg byte a +Statement [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) [ idx print::v_p1_x#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 ] ) always clobbers reg byte a reg byte x +Statement [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 print::v_p1_y#0 ] ) always clobbers reg byte a reg byte x +Removing always clobbered register reg byte a as potential for zp[1]:3 [ print::v_p1_x#0 ] +Removing always clobbered register reg byte x as potential for zp[1]:3 [ print::v_p1_x#0 ] +Statement [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] ) always clobbers reg byte a reg byte x +Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::v_p1_y#0 ] +Removing always clobbered register reg byte x as potential for zp[1]:4 [ print::v_p1_y#0 ] +Statement [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ) always clobbers reg byte a reg byte x +Removing always clobbered register reg byte a as potential for zp[1]:5 [ print::v_p2_x#0 ] +Removing always clobbered register reg byte x as potential for zp[1]:5 [ print::v_p2_x#0 ] +Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 [ idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp[1]:4 [ print::v_p1_y#0 ] +Removing always clobbered register reg byte y as potential for zp[1]:5 [ print::v_p2_x#0 ] +Removing always clobbered register reg byte a as potential for zp[1]:6 [ print::v_p2_y#0 ] +Removing always clobbered register reg byte y as potential for zp[1]:6 [ print::v_p2_y#0 ] +Statement [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 [ idx print::v_p2_x#0 print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p2_x#0 print::v_p2_y#0 ] ) always clobbers reg byte a reg byte y +Statement [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 [ idx print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p2_y#0 ] ) always clobbers reg byte a reg byte y +Statement [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 [ idx ] ( main:2::print:54 [ get::v main::i main::v idx ] ) always clobbers reg byte a reg byte y +Statement [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx ] ( main:2::print:54 [ get::v main::i main::v idx ] ) always clobbers reg byte a reg byte y +Statement [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::v ] ( main:2::get:41 [ idx main::i main::v get::i#0 get::v ] ) always clobbers reg byte a reg byte x +Statement [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::v ] ( main:2::get:41 [ idx main::i main::v get::i#0 get::$0 get::v ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:7 [ get::i#0 ] +Statement [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 [ get::i#0 get::$0 get::$1 get::$2 get::v ] ( main:2::get:41 [ idx main::i main::v get::i#0 get::$0 get::$1 get::$2 get::v ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:8 [ get::$0 ] +Removing always clobbered register reg byte a as potential for zp[1]:9 [ get::$1 ] +Statement [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 [ get::v get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ( main:2::get:41 [ idx main::i main::v get::v get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ) always clobbers reg byte x +Removing always clobbered register reg byte x as potential for zp[1]:12 [ get::return_p1_y#0 ] +Removing always clobbered register reg byte x as potential for zp[1]:13 [ get::return_p2_x#0 ] +Removing always clobbered register reg byte x as potential for zp[1]:14 [ get::return_p2_y#0 ] +Statement [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 [ get::v get::return_p2_x#0 get::return_p2_y#0 ] ( main:2::get:41 [ idx main::i main::v get::v get::return_p2_x#0 get::return_p2_y#0 ] ) always clobbers reg byte x +Statement [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 [ get::v get::return_p2_y#0 ] ( main:2::get:41 [ idx main::i main::v get::v get::return_p2_y#0 ] ) always clobbers reg byte x +Statement [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 [ get::v ] ( main:2::get:41 [ idx main::i main::v get::v ] ) always clobbers reg byte x +Statement [36] (byte) main::i ← (byte) 0 [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [37] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [39] stackpush(byte) ← (byte) main::i [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [42] (byte~) main::$1_p1_x ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::v ] ) always clobbers reg byte a +Statement [43] (byte~) main::$1_p1_y ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::v ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:16 [ main::$1_p1_x ] +Statement [44] (byte~) main::$1_p2_x ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::v ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:17 [ main::$1_p1_y ] +Statement [45] (byte~) main::$1_p2_y ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::$1_p2_y main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::$1_p2_y main::v ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:18 [ main::$1_p2_x ] +Statement [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement sideeffect stackpullbytes((number) 4) always clobbers reg byte a reg byte x +Statement [0] (byte) idx ← (byte) 0 [ idx get::v main::v ] ( [ idx get::v main::v ] ) always clobbers reg byte a +Statement [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) [ idx print::v_p1_x#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 ] ) always clobbers reg byte a reg byte x +Statement [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 print::v_p1_y#0 ] ) always clobbers reg byte a reg byte x +Statement [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 ] ) always clobbers reg byte a reg byte x +Statement [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) [ idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_x#0 print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ) always clobbers reg byte a reg byte x +Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 [ idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p1_y#0 print::v_p2_x#0 print::v_p2_y#0 ] ) always clobbers reg byte a reg byte y +Statement [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 [ idx print::v_p2_x#0 print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p2_x#0 print::v_p2_y#0 ] ) always clobbers reg byte a reg byte y +Statement [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 [ idx print::v_p2_y#0 ] ( main:2::print:54 [ get::v main::i main::v idx print::v_p2_y#0 ] ) always clobbers reg byte a reg byte y +Statement [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 [ idx ] ( main:2::print:54 [ get::v main::i main::v idx ] ) always clobbers reg byte a reg byte y +Statement [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx ] ( main:2::print:54 [ get::v main::i main::v idx ] ) always clobbers reg byte a reg byte y +Statement [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::v ] ( main:2::get:41 [ idx main::i main::v get::i#0 get::v ] ) always clobbers reg byte a reg byte x +Statement [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::v ] ( main:2::get:41 [ idx main::i main::v get::i#0 get::$0 get::v ] ) always clobbers reg byte a +Statement [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 [ get::i#0 get::$0 get::$1 get::$2 get::v ] ( main:2::get:41 [ idx main::i main::v get::i#0 get::$0 get::$1 get::$2 get::v ] ) always clobbers reg byte a +Statement [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 [ get::v get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ( main:2::get:41 [ idx main::i main::v get::v get::return_p1_y#0 get::return_p2_x#0 get::return_p2_y#0 ] ) always clobbers reg byte x +Statement [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 [ get::v get::return_p2_x#0 get::return_p2_y#0 ] ( main:2::get:41 [ idx main::i main::v get::v get::return_p2_x#0 get::return_p2_y#0 ] ) always clobbers reg byte x +Statement [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 [ get::v get::return_p2_y#0 ] ( main:2::get:41 [ idx main::i main::v get::v get::return_p2_y#0 ] ) always clobbers reg byte x +Statement [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 [ get::v ] ( main:2::get:41 [ idx main::i main::v get::v ] ) always clobbers reg byte x +Statement [36] (byte) main::i ← (byte) 0 [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [37] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [39] stackpush(byte) ← (byte) main::i [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [42] (byte~) main::$1_p1_x ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::v ] ) always clobbers reg byte a +Statement [43] (byte~) main::$1_p1_y ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::v ] ) always clobbers reg byte a +Statement [44] (byte~) main::$1_p2_x ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::v ] ) always clobbers reg byte a +Statement [45] (byte~) main::$1_p2_y ← stackpull(byte) [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::$1_p2_y main::v ] ( main:2 [ idx get::v main::i main::$1_p1_x main::$1_p1_y main::$1_p2_x main::$1_p2_y main::v ] ) always clobbers reg byte a +Statement [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::v main::i main::v ] ( main:2 [ idx get::v main::i main::v ] ) always clobbers reg byte a +Statement sideeffect stackpullbytes((number) 4) always clobbers reg byte a reg byte x +Potential registers zp[1]:2 [ idx ] : zp[1]:2 , +Potential registers zp[1]:3 [ print::v_p1_x#0 ] : zp[1]:3 , reg byte y , +Potential registers zp[1]:4 [ print::v_p1_y#0 ] : zp[1]:4 , +Potential registers zp[1]:5 [ print::v_p2_x#0 ] : zp[1]:5 , +Potential registers zp[1]:6 [ print::v_p2_y#0 ] : zp[1]:6 , reg byte x , +Potential registers zp[1]:7 [ get::i#0 ] : zp[1]:7 , reg byte x , reg byte y , +Potential registers zp[1]:8 [ get::$0 ] : zp[1]:8 , reg byte x , reg byte y , +Potential registers zp[1]:9 [ get::$1 ] : zp[1]:9 , reg byte x , reg byte y , +Potential registers zp[1]:10 [ get::$2 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:11 [ get::return_p1_x#0 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:12 [ get::return_p1_y#0 ] : zp[1]:12 , reg byte a , reg byte y , +Potential registers zp[1]:13 [ get::return_p2_x#0 ] : zp[1]:13 , reg byte a , reg byte y , +Potential registers zp[1]:14 [ get::return_p2_y#0 ] : zp[1]:14 , reg byte a , reg byte y , +Potential registers zp[1]:15 [ main::i ] : zp[1]:15 , +Potential registers zp[1]:16 [ main::$1_p1_x ] : zp[1]:16 , reg byte x , reg byte y , +Potential registers zp[1]:17 [ main::$1_p1_y ] : zp[1]:17 , reg byte x , reg byte y , +Potential registers zp[1]:18 [ main::$1_p2_x ] : zp[1]:18 , reg byte x , reg byte y , +Potential registers zp[1]:19 [ main::$1_p2_y ] : zp[1]:19 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:20 [ Vector::p1 ] : zp[2]:20 , +Potential registers zp[2]:22 [ Vector::p2 ] : zp[2]:22 , +Potential registers zp[4]:24 [ main::v ] : zp[4]:24 , +Potential registers zp[4]:28 [ get::v ] : zp[4]:28 , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 5.5: zp[1]:16 [ main::$1_p1_x ] 5.5: zp[1]:17 [ main::$1_p1_y ] 5.5: zp[1]:18 [ main::$1_p2_x ] 5.5: zp[1]:19 [ main::$1_p2_y ] 2.3: zp[1]:15 [ main::i ] 0: zp[4]:24 [ main::v ] +Uplift Scope [get] 2.5: zp[1]:7 [ get::i#0 ] 1: zp[1]:8 [ get::$0 ] 1: zp[1]:9 [ get::$1 ] 1: zp[1]:10 [ get::$2 ] 1: zp[1]:11 [ get::return_p1_x#0 ] 1: zp[1]:12 [ get::return_p1_y#0 ] 1: zp[1]:13 [ get::return_p2_x#0 ] 1: zp[1]:14 [ get::return_p2_y#0 ] 0: zp[4]:28 [ get::v ] +Uplift Scope [print] 1: zp[1]:3 [ print::v_p1_x#0 ] 0.8: zp[1]:4 [ print::v_p1_y#0 ] 0.67: zp[1]:5 [ print::v_p2_x#0 ] 0.57: zp[1]:6 [ print::v_p2_y#0 ] +Uplift Scope [] 0.86: zp[1]:2 [ idx ] +Uplift Scope [Point] +Uplift Scope [Vector] 0: zp[2]:20 [ Vector::p1 ] 0: zp[2]:22 [ Vector::p2 ] + +Uplifting [main] best 1566 combination reg byte y [ main::$1_p1_x ] reg byte x [ main::$1_p1_y ] zp[1]:18 [ main::$1_p2_x ] zp[1]:19 [ main::$1_p2_y ] zp[1]:15 [ main::i ] zp[4]:24 [ main::v ] +Limited combination testing to 100 combinations of 108 possible. +Uplifting [get] best 1555 combination reg byte y [ get::i#0 ] zp[1]:8 [ get::$0 ] reg byte x [ get::$1 ] zp[1]:10 [ get::$2 ] zp[1]:11 [ get::return_p1_x#0 ] zp[1]:12 [ get::return_p1_y#0 ] zp[1]:13 [ get::return_p2_x#0 ] zp[1]:14 [ get::return_p2_y#0 ] zp[4]:28 [ get::v ] +Limited combination testing to 100 combinations of 11664 possible. +Uplifting [print] best 1551 combination reg byte y [ print::v_p1_x#0 ] zp[1]:4 [ print::v_p1_y#0 ] zp[1]:5 [ print::v_p2_x#0 ] reg byte x [ print::v_p2_y#0 ] +Uplifting [] best 1551 combination zp[1]:2 [ idx ] +Uplifting [Point] best 1551 combination +Uplifting [Vector] best 1551 combination zp[2]:20 [ Vector::p1 ] zp[2]:22 [ Vector::p2 ] +Attempting to uplift remaining variables inzp[1]:18 [ main::$1_p2_x ] +Uplifting [main] best 1551 combination zp[1]:18 [ main::$1_p2_x ] +Attempting to uplift remaining variables inzp[1]:19 [ main::$1_p2_y ] +Uplifting [main] best 1551 combination zp[1]:19 [ main::$1_p2_y ] +Attempting to uplift remaining variables inzp[1]:15 [ main::i ] +Uplifting [main] best 1551 combination zp[1]:15 [ main::i ] +Attempting to uplift remaining variables inzp[1]:8 [ get::$0 ] +Uplifting [get] best 1551 combination zp[1]:8 [ get::$0 ] +Attempting to uplift remaining variables inzp[1]:10 [ get::$2 ] +Uplifting [get] best 1551 combination zp[1]:10 [ get::$2 ] +Attempting to uplift remaining variables inzp[1]:11 [ get::return_p1_x#0 ] +Uplifting [get] best 1547 combination reg byte x [ get::return_p1_x#0 ] +Attempting to uplift remaining variables inzp[1]:12 [ get::return_p1_y#0 ] +Uplifting [get] best 1543 combination reg byte y [ get::return_p1_y#0 ] +Attempting to uplift remaining variables inzp[1]:13 [ get::return_p2_x#0 ] +Uplifting [get] best 1543 combination zp[1]:13 [ get::return_p2_x#0 ] +Attempting to uplift remaining variables inzp[1]:14 [ get::return_p2_y#0 ] +Uplifting [get] best 1543 combination zp[1]:14 [ get::return_p2_y#0 ] +Attempting to uplift remaining variables inzp[1]:2 [ idx ] +Uplifting [] best 1543 combination zp[1]:2 [ idx ] +Attempting to uplift remaining variables inzp[1]:4 [ print::v_p1_y#0 ] +Uplifting [print] best 1543 combination zp[1]:4 [ print::v_p1_y#0 ] +Attempting to uplift remaining variables inzp[1]:5 [ print::v_p2_x#0 ] +Uplifting [print] best 1543 combination zp[1]:5 [ print::v_p2_x#0 ] +Coalescing zero page register [ zp[1]:8 [ get::$0 ] ] with [ zp[1]:4 [ print::v_p1_y#0 ] ] +Coalescing zero page register [ zp[1]:10 [ get::$2 ] ] with [ zp[1]:5 [ print::v_p2_x#0 ] ] +Coalescing zero page register [ zp[1]:18 [ main::$1_p2_x ] ] with [ zp[1]:13 [ get::return_p2_x#0 ] ] +Coalescing zero page register [ zp[1]:19 [ main::$1_p2_y ] ] with [ zp[1]:14 [ get::return_p2_y#0 ] ] +Allocated (was zp[1]:8) zp[1]:3 [ get::$0 print::v_p1_y#0 ] +Allocated (was zp[1]:10) zp[1]:4 [ get::$2 print::v_p2_x#0 ] +Allocated (was zp[1]:15) zp[1]:5 [ main::i ] +Allocated (was zp[1]:18) zp[1]:6 [ main::$1_p2_x get::return_p2_x#0 ] +Allocated (was zp[1]:19) zp[1]:7 [ main::$1_p2_y get::return_p2_y#0 ] +Allocated (was zp[2]:20) zp[2]:8 [ Vector::p1 ] +Allocated (was zp[2]:22) zp[2]:10 [ Vector::p2 ] +Allocated (was zp[4]:24) zp[4]:12 [ main::v ] +Allocated (was zp[4]:28) zp[4]:16 [ get::v ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Test a procedure with calling convention stack +// Returning and passing struct of struct values + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const STACK_BASE = $103 + .label idx = 2 + // @begin +__bbegin: + // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] callexecute main -- jsr + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // print +// print(byte register(Y) v_p1_x, byte zp(3) v_p1_y, byte zp(4) v_p2_x, byte register(X) v_p2_y) +print: { + .const OFFSET_STACK_V_P1_X = 3 + .const OFFSET_STACK_V_P1_Y = 2 + .const OFFSET_STACK_V_P2_X = 1 + .const OFFSET_STACK_V_P2_Y = 0 + .label v_p1_y = 3 + .label v_p2_x = 4 + // [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) -- vbuyy=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_X,x + tay + // [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_Y,x + sta.z v_p1_y + // [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_X,x + sta.z v_p2_x + // [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) -- vbuxx=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_Y,x + tax + // [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 -- pbuc1_derefidx_vbuz1=vbuyy + tya + ldy.z idx + sta SCREEN,y + // [9] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p1_y + ldy.z idx + sta SCREEN,y + // [11] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p2_x + ldy.z idx + sta SCREEN,y + // [13] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 -- pbuc1_derefidx_vbuz1=vbuxx + ldy.z idx + txa + sta SCREEN,y + // [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #' ' + ldy.z idx + sta SCREEN,y + // [17] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + jmp __breturn + // print::@return + __breturn: + // [18] return + rts +} + // get +// get(byte register(Y) i) +get: { + .const OFFSET_STACK_I = 0 + .label __0 = 3 + .label __2 = 4 + .label v = $10 + .label return_p2_x = 6 + .label return_p2_y = 7 + // [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuyy=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_I,x + tay + // [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuz1=vbuyy_ror_1 + tya + lsr + sta.z __0 + // [21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1 -- vbuxx=vbuyy_plus_1 + tya + tax + inx + // [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 -- vbuz1=vbuyy_rol_1 + tya + asl + sta.z __2 + // [23] *((byte*)(struct Point*)&(struct Vector) get::v) ← (byte) get::i#0 -- _deref_pbuc1=vbuyy + sty.z v + // [24] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuz1 + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + // [25] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) get::$1 -- _deref_pbuc1=vbuxx + stx v+OFFSET_STRUCT_VECTOR_P2 + // [26] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$2 -- _deref_pbuc1=vbuz1 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // [27] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v) -- vbuxx=_deref_pbuc1 + ldx.z v + // [28] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuyy=_deref_pbuc1 + ldy v+OFFSET_STRUCT_POINT_Y + // [29] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2 + sta.z return_p2_x + // [30] (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + sta.z return_p2_y + jmp __breturn + // get::@return + __breturn: + // [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 -- _stackidxbyte_vbuc1=vbuxx + txa + tsx + sta STACK_BASE+0,x + // [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 -- _stackidxbyte_vbuc1=vbuyy + tya + tsx + sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x + // [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p2_x + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x + // [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p2_y + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x + // [35] return + rts +} + // main +main: { + .label i = 5 + .label v = $c + .label __1_p2_x = 6 + .label __1_p2_y = 7 + // [36] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z i + jmp __b1 + // main::@1 + __b1: + // [37] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z i + cmp #5 + bcc __b2 + jmp __breturn + // main::@return + __breturn: + // [38] return + rts + // main::@2 + __b2: + // [39] stackpush(byte) ← (byte) main::i -- _stackpushbyte_=vbuz1 + lda.z i + pha + // sideeffect stackpushbytes((number) 3) -- _stackpushbyte_3 + pha + pha + pha + // [41] callexecute get -- jsr + jsr get + // [42] (byte~) main::$1_p1_x ← stackpull(byte) -- vbuyy=_stackpullbyte_ + pla + tay + // [43] (byte~) main::$1_p1_y ← stackpull(byte) -- vbuxx=_stackpullbyte_ + pla + tax + // [44] (byte~) main::$1_p2_x ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p2_x + // [45] (byte~) main::$1_p2_y ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p2_y + // [46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x -- _deref_pbuc1=vbuyy + sty.z v + // [47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y -- _deref_pbuc1=vbuxx + stx v+OFFSET_STRUCT_POINT_Y + // [48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x -- _deref_pbuc1=vbuz1 + lda.z __1_p2_x + sta v+OFFSET_STRUCT_VECTOR_P2 + // [49] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y -- _deref_pbuc1=vbuz1 + lda.z __1_p2_y + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _stackpushbyte_=_deref_pbuc1 + lda.z v + pha + // [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_POINT_Y + pha + // [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2 + pha + // [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + pha + // [54] callexecute print -- jsr + jsr print + // sideeffect stackpullbytes((number) 4) -- _stackpullbyte_4 + tsx + txa + axs #-4 + txs + // [56] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + inc.z i + jmp __b1 +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing instruction lda.z v with TYA +Replacing instruction lda v+OFFSET_STRUCT_POINT_Y with TXA +Removing instruction __b1_from___bbegin: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __b1: +Removing instruction __bend: +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Adding RTS to root block +Succesful ASM optimization Pass5AddMainRts + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1 +(const byte) OFFSET_STRUCT_VECTOR_P2 = (byte) 2 +(byte) Point::x loadstore +(byte) Point::y loadstore +(const byte*) SCREEN = (byte*) 1024 +(const word) STACK_BASE = (word) $103 +(struct Point) Vector::p1 loadstore zp[2]:8 +(struct Point) Vector::p2 loadstore zp[2]:10 +__stackcall (struct Vector()) get((byte) get::i) +(byte~) get::$0 zp[1]:3 1.0 +(byte~) get::$1 reg byte x 1.0 +(byte~) get::$2 zp[1]:4 1.0 +(label) get::@return +(const byte) get::OFFSET_STACK_I = (byte) 0 +(byte) get::i +(byte) get::i#0 reg byte y 2.5 +(struct Vector) get::return +(struct Point) get::return_p1 +(byte) get::return_p1_x +(byte) get::return_p1_x#0 reg byte x 1.0 +(byte) get::return_p1_y +(byte) get::return_p1_y#0 reg byte y 1.0 +(struct Point) get::return_p2 +(byte) get::return_p2_x +(byte) get::return_p2_x#0 return_p2_x zp[1]:6 1.0 +(byte) get::return_p2_y +(byte) get::return_p2_y#0 return_p2_y zp[1]:7 1.0 +(struct Vector) get::v loadstore zp[4]:16 +(byte) idx loadstore zp[1]:2 0.8648648648648649 +__stackcall (void()) main() +(byte~) main::$1_p1_x reg byte y 5.5 +(byte~) main::$1_p1_y reg byte x 5.5 +(byte~) main::$1_p2_x zp[1]:6 5.5 +(byte~) main::$1_p2_y zp[1]:7 5.5 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::i loadstore zp[1]:5 2.3000000000000003 +(struct Vector) main::v loadstore zp[4]:12 +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +(label) print::@return +(const byte) print::OFFSET_STACK_V_P1_X = (byte) 3 +(const byte) print::OFFSET_STACK_V_P1_Y = (byte) 2 +(const byte) print::OFFSET_STACK_V_P2_X = (byte) 1 +(const byte) print::OFFSET_STACK_V_P2_Y = (byte) 0 +(struct Point) print::v_p1 +(byte) print::v_p1_x +(byte) print::v_p1_x#0 reg byte y 1.0 +(byte) print::v_p1_y +(byte) print::v_p1_y#0 v_p1_y zp[1]:3 0.8 +(struct Point) print::v_p2 +(byte) print::v_p2_x +(byte) print::v_p2_x#0 v_p2_x zp[1]:4 0.6666666666666666 +(byte) print::v_p2_y +(byte) print::v_p2_y#0 reg byte x 0.5714285714285714 + +zp[1]:2 [ idx ] +reg byte y [ print::v_p1_x#0 ] +reg byte x [ print::v_p2_y#0 ] +reg byte y [ get::i#0 ] +zp[1]:3 [ get::$0 print::v_p1_y#0 ] +reg byte x [ get::$1 ] +zp[1]:4 [ get::$2 print::v_p2_x#0 ] +reg byte x [ get::return_p1_x#0 ] +reg byte y [ get::return_p1_y#0 ] +zp[1]:5 [ main::i ] +reg byte y [ main::$1_p1_x ] +reg byte x [ main::$1_p1_y ] +zp[1]:6 [ main::$1_p2_x get::return_p2_x#0 ] +zp[1]:7 [ main::$1_p2_y get::return_p2_y#0 ] +zp[2]:8 [ Vector::p1 ] +zp[2]:10 [ Vector::p2 ] +zp[4]:12 [ main::v ] +zp[4]:16 [ get::v ] + + +FINAL ASSEMBLER +Score: 1474 + + // File Comments +// Test a procedure with calling convention stack +// Returning and passing struct of struct values + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_VECTOR_P2 = 2 + .const STACK_BASE = $103 + .label idx = 2 + // @begin +__bbegin: + // idx = 0 + // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] callexecute main -- jsr + jsr main + rts + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // print +// print(byte register(Y) v_p1_x, byte zp(3) v_p1_y, byte zp(4) v_p2_x, byte register(X) v_p2_y) +print: { + .const OFFSET_STACK_V_P1_X = 3 + .const OFFSET_STACK_V_P1_Y = 2 + .const OFFSET_STACK_V_P2_X = 1 + .const OFFSET_STACK_V_P2_Y = 0 + .label v_p1_y = 3 + .label v_p2_x = 4 + // } + // [4] (byte) print::v_p1_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_X) -- vbuyy=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_X,x + tay + // [5] (byte) print::v_p1_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P1_Y) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P1_Y,x + sta.z v_p1_y + // [6] (byte) print::v_p2_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_X) -- vbuz1=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_X,x + sta.z v_p2_x + // [7] (byte) print::v_p2_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_V_P2_Y) -- vbuxx=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_V_P2_Y,x + tax + // SCREEN[idx++] = v.p1.x + // [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_x#0 -- pbuc1_derefidx_vbuz1=vbuyy + tya + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = v.p1.x; + // [9] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // SCREEN[idx++] = v.p1.y + // [10] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p1_y#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p1_y + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = v.p1.y; + // [11] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // SCREEN[idx++] = v.p2.x + // [12] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_x#0 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z v_p2_x + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = v.p2.x; + // [13] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // SCREEN[idx++] = v.p2.y + // [14] *((const byte*) SCREEN + (byte) idx) ← (byte) print::v_p2_y#0 -- pbuc1_derefidx_vbuz1=vbuxx + ldy.z idx + txa + sta SCREEN,y + // SCREEN[idx++] = v.p2.y; + // [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // SCREEN[idx++] = ' ' + // [16] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #' ' + ldy.z idx + sta SCREEN,y + // SCREEN[idx++] = ' '; + // [17] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 + inc.z idx + // print::@return + // } + // [18] return + rts +} + // get +// get(byte register(Y) i) +get: { + .const OFFSET_STACK_I = 0 + .label __0 = 3 + .label __2 = 4 + .label v = $10 + .label return_p2_x = 6 + .label return_p2_y = 7 + // [19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuyy=_stackidxbyte_vbuc1 + tsx + lda STACK_BASE+OFFSET_STACK_I,x + tay + // i/2 + // [20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuz1=vbuyy_ror_1 + tya + lsr + sta.z __0 + // i+1 + // [21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1 -- vbuxx=vbuyy_plus_1 + tya + tax + inx + // i*2 + // [22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 -- vbuz1=vbuyy_rol_1 + tya + asl + sta.z __2 + // v = { {i, i/2}, {i+1, i*2} } + // [23] *((byte*)(struct Point*)&(struct Vector) get::v) ← (byte) get::i#0 -- _deref_pbuc1=vbuyy + sty.z v + // [24] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuz1 + lda.z __0 + sta v+OFFSET_STRUCT_POINT_Y + // [25] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) get::$1 -- _deref_pbuc1=vbuxx + stx v+OFFSET_STRUCT_VECTOR_P2 + // [26] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$2 -- _deref_pbuc1=vbuz1 + lda.z __2 + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // return v; + // [27] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v) -- vbuxx=_deref_pbuc1 + ldx.z v + // [28] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuyy=_deref_pbuc1 + ldy v+OFFSET_STRUCT_POINT_Y + // [29] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2 + sta.z return_p2_x + // [30] (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + sta.z return_p2_y + // get::@return + // } + // [31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 -- _stackidxbyte_vbuc1=vbuxx + txa + tsx + sta STACK_BASE+0,x + // [32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 -- _stackidxbyte_vbuc1=vbuyy + tya + tsx + sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x + // [33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p2_x + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x + // [34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 -- _stackidxbyte_vbuc1=vbuz1 + lda.z return_p2_y + tsx + sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y,x + // [35] return + rts +} + // main +main: { + .label i = 5 + .label v = $c + .label __1_p2_x = 6 + .label __1_p2_y = 7 + // i=0 + // [36] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z i + // main::@1 + __b1: + // for(char i=0;i<5;i++) + // [37] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z i + cmp #5 + bcc __b2 + // main::@return + // } + // [38] return + rts + // main::@2 + __b2: + // get(i) + // [39] stackpush(byte) ← (byte) main::i -- _stackpushbyte_=vbuz1 + lda.z i + pha + // sideeffect stackpushbytes((number) 3) -- _stackpushbyte_3 + pha + pha + pha + // [41] callexecute get -- jsr + jsr get + // [42] (byte~) main::$1_p1_x ← stackpull(byte) -- vbuyy=_stackpullbyte_ + pla + tay + // [43] (byte~) main::$1_p1_y ← stackpull(byte) -- vbuxx=_stackpullbyte_ + pla + tax + // [44] (byte~) main::$1_p2_x ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p2_x + // [45] (byte~) main::$1_p2_y ← stackpull(byte) -- vbuz1=_stackpullbyte_ + pla + sta.z __1_p2_y + // v = get(i) + // [46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x -- _deref_pbuc1=vbuyy + sty.z v + // [47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y -- _deref_pbuc1=vbuxx + stx v+OFFSET_STRUCT_POINT_Y + // [48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x -- _deref_pbuc1=vbuz1 + lda.z __1_p2_x + sta v+OFFSET_STRUCT_VECTOR_P2 + // [49] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y -- _deref_pbuc1=vbuz1 + lda.z __1_p2_y + sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + // print(v) + // [50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _stackpushbyte_=_deref_pbuc1 + tya + pha + // [51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 + txa + pha + // [52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2 + pha + // [53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 + lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y + pha + // [54] callexecute print -- jsr + jsr print + // sideeffect stackpullbytes((number) 4) -- _stackpullbyte_4 + tsx + txa + axs #-4 + txs + // for(char i=0;i<5;i++) + // [56] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + inc.z i + jmp __b1 +} + // File Data + diff --git a/src/test/ref/procedure-callingconvention-stack-11.sym b/src/test/ref/procedure-callingconvention-stack-11.sym new file mode 100644 index 000000000..c9708abc4 --- /dev/null +++ b/src/test/ref/procedure-callingconvention-stack-11.sym @@ -0,0 +1,77 @@ +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1 +(const byte) OFFSET_STRUCT_VECTOR_P2 = (byte) 2 +(byte) Point::x loadstore +(byte) Point::y loadstore +(const byte*) SCREEN = (byte*) 1024 +(const word) STACK_BASE = (word) $103 +(struct Point) Vector::p1 loadstore zp[2]:8 +(struct Point) Vector::p2 loadstore zp[2]:10 +__stackcall (struct Vector()) get((byte) get::i) +(byte~) get::$0 zp[1]:3 1.0 +(byte~) get::$1 reg byte x 1.0 +(byte~) get::$2 zp[1]:4 1.0 +(label) get::@return +(const byte) get::OFFSET_STACK_I = (byte) 0 +(byte) get::i +(byte) get::i#0 reg byte y 2.5 +(struct Vector) get::return +(struct Point) get::return_p1 +(byte) get::return_p1_x +(byte) get::return_p1_x#0 reg byte x 1.0 +(byte) get::return_p1_y +(byte) get::return_p1_y#0 reg byte y 1.0 +(struct Point) get::return_p2 +(byte) get::return_p2_x +(byte) get::return_p2_x#0 return_p2_x zp[1]:6 1.0 +(byte) get::return_p2_y +(byte) get::return_p2_y#0 return_p2_y zp[1]:7 1.0 +(struct Vector) get::v loadstore zp[4]:16 +(byte) idx loadstore zp[1]:2 0.8648648648648649 +__stackcall (void()) main() +(byte~) main::$1_p1_x reg byte y 5.5 +(byte~) main::$1_p1_y reg byte x 5.5 +(byte~) main::$1_p2_x zp[1]:6 5.5 +(byte~) main::$1_p2_y zp[1]:7 5.5 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::i loadstore zp[1]:5 2.3000000000000003 +(struct Vector) main::v loadstore zp[4]:12 +__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) +(label) print::@return +(const byte) print::OFFSET_STACK_V_P1_X = (byte) 3 +(const byte) print::OFFSET_STACK_V_P1_Y = (byte) 2 +(const byte) print::OFFSET_STACK_V_P2_X = (byte) 1 +(const byte) print::OFFSET_STACK_V_P2_Y = (byte) 0 +(struct Point) print::v_p1 +(byte) print::v_p1_x +(byte) print::v_p1_x#0 reg byte y 1.0 +(byte) print::v_p1_y +(byte) print::v_p1_y#0 v_p1_y zp[1]:3 0.8 +(struct Point) print::v_p2 +(byte) print::v_p2_x +(byte) print::v_p2_x#0 v_p2_x zp[1]:4 0.6666666666666666 +(byte) print::v_p2_y +(byte) print::v_p2_y#0 reg byte x 0.5714285714285714 + +zp[1]:2 [ idx ] +reg byte y [ print::v_p1_x#0 ] +reg byte x [ print::v_p2_y#0 ] +reg byte y [ get::i#0 ] +zp[1]:3 [ get::$0 print::v_p1_y#0 ] +reg byte x [ get::$1 ] +zp[1]:4 [ get::$2 print::v_p2_x#0 ] +reg byte x [ get::return_p1_x#0 ] +reg byte y [ get::return_p1_y#0 ] +zp[1]:5 [ main::i ] +reg byte y [ main::$1_p1_x ] +reg byte x [ main::$1_p1_y ] +zp[1]:6 [ main::$1_p2_x get::return_p2_x#0 ] +zp[1]:7 [ main::$1_p2_y get::return_p2_y#0 ] +zp[2]:8 [ Vector::p1 ] +zp[2]:10 [ Vector::p2 ] +zp[4]:12 [ main::v ] +zp[4]:16 [ get::v ]