1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-08-08 13:25:12 +00:00

- near, close, far implementation using fragments for phi calls

- fragment consolidation
- removal of platform
- stackcall banked throws error
- testing
This commit is contained in:
Sven Van de Velde
2023-04-11 08:35:18 +02:00
parent a52b5dc4a9
commit b62430bfc3
116 changed files with 4669 additions and 8620 deletions

View File

@@ -0,0 +1,6 @@
lda #{c1}
sta $0
pha
jsr {la1}
pla
sta $0

View File

@@ -0,0 +1,7 @@
lda #{c1}
sta $1
pha
jsr {la1}
pla
sta $1

View File

@@ -0,0 +1 @@
jsr {la1}

View File

@@ -0,0 +1,14 @@
// Test a procedure with calling convention PHI - case #1
#pragma code_seg(Code)
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
void main(void) {
SCREEN[0] = plus('0', 7);
}
char plus(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,14 @@
// Test a procedure with calling convention PHI - case #1
#pragma code_seg(Code)
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
void main(void) {
SCREEN[0] = plus('0', 7);
}
char plus(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,17 @@
// Test a procedure with calling convention PHI - case #2
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(RAM_Bank1)
__bank(cx16_ram,1) char plus(char a, char b) {
return a+b;
}
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}

View File

@@ -0,0 +1,17 @@
// Test a procedure with calling convention PHI - case #2
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(RAM_Bank1)
__bank(cx16_ram,1) char plus(char a, char b) {
return a+b;
}
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}

View File

@@ -0,0 +1,22 @@
// Test a procedure with calling convention PHI - case #3
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
char min(char a, char b) {
return a+b;
}
#pragma code_seg(RAM_Bank1)
__bank(cx16_ram,1) char plus(char a, char b) {
return min(a, b);
}
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}

View File

@@ -0,0 +1,22 @@
// Test a procedure with calling convention PHI - case #3
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
char min(char a, char b) {
return a+b;
}
#pragma code_seg(RAM_Bank1)
__bank(cx16_ram,1) char plus(char a, char b) {
return min(a, b);
}
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}

View File

@@ -0,0 +1,21 @@
// Test a procedure with calling convention PHI - case #4
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b);
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) min(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,21 @@
// Test a procedure with calling convention PHI - case #4
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b);
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) min(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,21 @@
// Test a procedure with calling convention PHI - case #4
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b);
}
#pragma code_seg(RAM_Bank2)
char __bank(cx16_ram, 2) min(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,21 @@
// Test a procedure with calling convention PHI - case #4
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b);
}
#pragma code_seg(RAM_Bank2)
char __bank(cx16_ram, 2) min(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,20 @@
// Test a procedure with calling convention PHI - case #6
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7); // close call
}
#pragma code_seg(RAM_Bank1)
__bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b); // near call
}
#pragma code_seg(ROM_Bank1)
__bank(cx16_rom, 1) min(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,25 @@
// Test a procedure with calling convention PHI - case #6
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7); // close call
}
#pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1)
char plus(char a, char b) {
return min(a, b); // near call
}
#pragma code_seg(ROM_Bank1)
#pragma bank(cx16_rom, 1)
char min(char a, char b) {
return a+b;
}
#pragma code_seg(Code)
#pragma nobank(dummy)

View File

@@ -0,0 +1,15 @@
// Test a procedure with calling convention PHI - case #1
#pragma link("call-banked-stack.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7); // near stack call
}
#pragma code_seg(Code)
__stackcall char plus(char a, char b) {
return a+b;
}

View File

@@ -0,0 +1,20 @@
// Test a procedure with calling convention PHI - case #4
#pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code)
void main(void) {
SCREEN[0] = plus('0', 7); // close call
}
#pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b); // far call
}
#pragma code_seg(RAM_Bank2)
char __bank(cx16_ram, 2) min(char a, char b) {
return a+b;
}

View File

@@ -1,10 +1,11 @@
.file [name="%O", type="prg", segments="Program"] .file [name="%O", type="prg", segments="Program"]
.file [name="BANK1.BIN", type="bin", segments="Bank1"]
.segmentdef Program [segments="Basic, Code, Data"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=%P] .segmentdef Code [start=%P]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic .segment Basic
:BasicUpstart(%E) :BasicUpstart(%E)
.segment Code .segment Code

View File

@@ -1,55 +0,0 @@
/**
* @file cx16-banking-1.c
* @author your name (you@domain.com)
* @brief This program demonstrates a simple example of a banked call.
* @version 0.1
* @date 2023-04-05
*
* @copyright Copyright (c) 2023
*
*/
// The linker specification of the different segments.
#pragma link("cx16-banking-1.ld")
#pragma var_model(mem)
#include <cx16.h>
#include <conio.h>
#include <printf.h>
#include <kernal.h>
#include "cx16-banking-0.h"
// The target computer platform is the Commander X16,
// which implements banking in ram between 0xA0000 and 0xBFFF,
// and in ram between 0xC000 and 0xFFFF.
#pragma target(cx16)
char* const SCREEN = (char*)0x0400;
#pragma code_seg(Bank1) // The sequent functions will be addressed specified by segment bank1 in the linker.
#pragma bank(ram, 1) // The sequent functions will be banked using call method ram in bank number 1.
char __stackcall plus(char a, char b) {
return a+b;
}
#pragma code_seg(Code) // The sequent functions will be addressed in the default main memory location (segment Code).
#pragma nobank(dummy) // The sequent functions will consider no banking calculations anymore.
void load_bank(char bank, char *file) {
bank_set_bram(bank);
cbm_k_setnam(file);
cbm_k_setlfs(1,8,2);
cbm_k_load((char*)0xA000, 0);
cbm_k_close(1);
}
void main(void) {
load_bank(1, "BANK1.BIN");
SCREEN[0] = plus('0', 7);
}

View File

@@ -16,10 +16,7 @@
#include <cx16.h> #include <cx16.h>
#include <conio.h> #include <conio.h>
#include <printf.h> #include <printf.h>
#include <kernal.h> #include <cx16-kernal.h>
#include "cx16-banking-1.h"
// The target computer platform is the Commander X16, // The target computer platform is the Commander X16,
// which implements banking in ram between 0xA0000 and 0xBFFF, // which implements banking in ram between 0xA0000 and 0xBFFF,

View File

@@ -1,15 +0,0 @@
// Test a procedure with calling convention PHI
#pragma code_seg(stage)
#pragma link("procedure-callingconvention-phi-bank.ld")
#pragma target(cx16)
char* const SCREEN = (char*)0x0400;
void main(void) {
SCREEN[0] = plus('0', 7);
}
char __bank(ram,2) plus(char a, char b) {
return a+b;
}

View File

@@ -1,18 +0,0 @@
// Test a far call procedure with a calling convention PHI
#pragma code_seg(stage)
#pragma link("procedure-callingconvention-phi-bank.ld")
#pragma target(cx16)
char* const SCREEN = (char*)0x0400;
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(stage)
#pragma bank(ram, 1)
char plus(char a, char b) {
return a+b;
}

View File

@@ -1,19 +0,0 @@
// Test a far call procedure with a calling convention PHI into ROM
#pragma code_seg(stage)
#pragma link("procedure-callingconvention-phi-bank.ld")
#pragma target(cx16)
char* const SCREEN = (char*)0x0400;
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(stage)
#pragma bank(rom, 1) // test rom bank
char plus(char a, char b) {
return a+b;
}

View File

@@ -1,21 +0,0 @@
// Test a far call procedure with a calling convention PHI
#pragma code_seg(stage)
#pragma link("procedure-callingconvention-phi-bank.ld")
#pragma target(cx16)
char* const SCREEN = (char*)0x0400;
void main(void) {
SCREEN[0] = plus('0', 7);
}
#pragma code_seg(stage)
#pragma bank(rom, 2) // Test rom fragment
char plus(char a, char b) {
return a+b;
}
#pragma nobank(dummy)

View File

@@ -1,20 +0,0 @@
// Test a far call procedure with a calling convention phi
#pragma link("procedure-callingconvention-phi-bank.ld")
#pragma target(cx16)
char* const SCREEN = (char*)0x0400;
#pragma code_seg(stage)
#pragma bank(ram, 20)
char plus(char a, char b) {
return a+b;
}
#pragma nobank(dummy)
void main(void) {
SCREEN[0] = plus('0', 7);
}

View File

@@ -1,119 +0,0 @@
// The linker specification of the different segments.
#pragma link("procedure-callingconvention-phi-bank-5.ld")
// The target computer platform is the Commander X16,
// which implements banking in ram between 0xA0000 and 0xBFFF,
// and in rom between 0xC000 and 0xFFFF.
#pragma target(cx16)
char *const SCREEN = (char *)0x0400; // Just for test purposes.
#pragma code_seg(Bank1) // The sequent functions will be addressed specified by segment bank1 in the linker.
#pragma bank(ram, 1) // The sequent functions will be banked using call method ram in bank number 1.
// Function declarations
char func_ram_bank1_a(char a, char b);
char __bank(ram, 1) func_ram_bank1_b(char a, char b);
char func_ram_bank1_c(char a, char b);
char func_ram_bank1_d(char a, char b);
char func_ram_bank1_e(char a, char b);
char func_ram_bank1_f(char a, char b);
char func_rom_bank2_a(char a, char b);
char __bank(rom, 2) func_rom_bank2_b(char a, char b);
char func_rom_bank2_c(char a, char b);
char func_rom_bank2_d(char a, char b);
char func_rom_bank2_e(char a, char b);
char func_rom_bank2_f(char a, char b);
char func_main_a(char a, char b);
char func_main_b(char a, char b);
// Functional code
char func_ram_bank1_a(char a, char b) {
return a + b;
}
char func_ram_bank1_c(char a, char b) {
return func_ram_bank1_a(a, b); // Non banked call in ram bank 1.
}
char func_ram_bank1_d(char a, char b) {
return func_rom_bank2_a(a, b); // Banked call from ram bank 1 to rom bank 2.
}
char func_ram_bank1_e(char a, char b) {
return func_rom_bank2_b(a, b); // Banked call from ram bank 1 to rom bank 2.
}
char func_ram_bank1_f(char a, char b) {
return func_main_a(a, b); // Non banked call from ram bank 1 to main memory.
}
#pragma code_seg(Bank2) // The sequent functions will be addressed specified by segment bank2 in the linker.
#pragma bank(rom, 2) // The sequent functions will be banked using call method rom in bank number 2.
char func_rom_bank2_a(char a, char b) {
return a + b;
}
char func_rom_bank2_c(char a, char b) {
return func_ram_bank1_a(a, b); // Banked call from rom bank 2 to ram bank 1.
}
char func_rom_bank2_d(char a, char b) {
return func_rom_bank2_a(a, b); // Non banked call in rom bank 2.
}
char func_rom_bank2_e(char a, char b) {
return func_rom_bank2_b(a, b); // Non Banked call in rom bank 2.
}
char func_rom_bank2_f(char a, char b) {
return func_main_a(a, b); // Non banked call from rom bank 2 to main memory.
}
#pragma nobank(dummy) // The sequent functions will consider no banking calculations anymore.
// The __bank directive declares this function to be banked using call method ram in bank number 1 of banked ram.
char __bank(ram, 1) func_ram_bank1_b(char a, char b) {
return a + b;
}
// The __bank directive declares this function to be banked using call method rom in bank number 2 of banked rom.
char __bank(rom, 2) func_rom_bank2_b(char a, char b) {
return a + b;
}
#pragma code_seg(Code) // The sequent functions will be addressed in the default main memory location (segment Code).
// Allocated in main memory.
char func_main_a(char a, char b) {
return func_ram_bank1_e(a, b); // Banked call to ram in bank 1 from main memory.
}
// Allocated in main memory.
char func_main_b(char a, char b) {
return func_rom_bank2_e(a, b); // Banked call to rom in bank 2 from main memory.
}
// Practically this means that the main() function is placed in main memory ...
void main(void) {
SCREEN[0] = func_ram_bank1_a('0', 7); // Banked call to ram in bank 1 from main memory.
SCREEN[0] = func_ram_bank1_b('0', 7); // Banked call to ram in bank 1 from main memory.
SCREEN[0] = func_ram_bank1_c('0', 7); // Banked call to ram in bank 1 from main memory.
SCREEN[0] = func_ram_bank1_d('0', 7); // Banked call to ram in bank 1 from main memory.
SCREEN[0] = func_ram_bank1_e('0', 7); // Banked call to ram in bank 1 from main memory.
SCREEN[0] = func_ram_bank1_f('0', 7); // Banked call to ram in bank 1 from main memory.
SCREEN[0] = func_rom_bank2_a('0', 7); // Banked call to rom in bank 2 from main memory.
SCREEN[0] = func_rom_bank2_b('0', 7); // Banked call to rom in bank 2 from main memory.
SCREEN[0] = func_rom_bank2_c('0', 7); // Banked call to rom in bank 2 from main memory.
SCREEN[0] = func_rom_bank2_d('0', 7); // Banked call to rom in bank 2 from main memory.
SCREEN[0] = func_rom_bank2_e('0', 7); // banked call to rom in bank 2 from main memory.
SCREEN[0] = func_rom_bank2_f('0', 7); // banked call to rom in bank 2 from main memory.
SCREEN[0] = func_main_a('0', 7); // Near call in main memory from main memory.
SCREEN[0] = func_main_b('0', 7); // Near call in main memory from main memory.
}

View File

@@ -1,7 +0,0 @@
.segmentdef Program [segments="Basic, Code, Data, Bank1, Bank2"]
.segmentdef Basic [start=$0801]a
.segmentdef Code [start=%P]
.segmentdef Data [startAfter="Code"]
.segmentdef Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef Bank2 [start=$C000, min=$C000, max=$FFFF, align=$100]

View File

@@ -0,0 +1,33 @@
// Test a procedure with calling convention PHI - case #1
.file [name="call-banked-phi-case-1-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
jsr plus
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,4 +1,4 @@
Loading link script "procedure-callingconvention-phi-bank.ld" Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@@ -157,24 +157,29 @@ Uplifting [] best 60 combination
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
// Test a procedure with calling convention PHI // Test a procedure with calling convention PHI - case #1
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-1-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] // [4] phi from main to plus [phi:main->plus] -- call__phi_near_finalize
plus_from_main: plus_from_main:
jsr plus jsr plus
jmp __b1 jmp __b1
@@ -231,25 +236,30 @@ FINAL ASSEMBLER
Score: 24 Score: 24
// File Comments // File Comments
// Test a procedure with calling convention PHI // Test a procedure with calling convention PHI - case #1
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-1-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] // [4] phi from main to plus [phi:main->plus] -- call__phi_near_finalize
jsr plus jsr plus
// main::@1 // main::@1
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)

View File

@@ -0,0 +1,40 @@
// Test a procedure with calling convention PHI - case #1
.file [name="call-banked-phi-case-1-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
jsr plus
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr min
// }
rts
}
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,386 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
char min(char a , char b)
char min::a
char min::b
char min::return
char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 75 combination
Uplifting [plus] best 75 combination
Uplifting [min] best 75 combination
Uplifting [] best 75 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #1
// Upstart
.file [name="call-banked-phi-case-1-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call__phi_near_finalize
plus_from_main:
jsr plus
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
min_from_plus:
jsr min
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 36
// File Comments
// Test a procedure with calling convention PHI - case #1
// Upstart
.file [name="call-banked-phi-case-1-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call__phi_near_finalize
jsr plus
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
jsr min
// plus::@return
// }
// [6] return
rts
}
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -0,0 +1,39 @@
// Test a procedure with calling convention PHI - case #2
.file [name="call-banked-phi-case-2-close-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,4 +1,4 @@
Loading link script "procedure-callingconvention-phi-bank.ld" Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@@ -144,6 +144,7 @@ char plus::return
Initial phi equivalence classes Initial phi equivalence classes
Complete equivalence classes Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
@@ -151,35 +152,42 @@ Uplift Scope [main]
Uplift Scope [plus] Uplift Scope [plus]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 60 combination Uplifting [main] best 75 combination
Uplifting [plus] best 60 combination Uplifting [plus] best 75 combination
Uplifting [] best 60 combination Uplifting [] best 75 combination
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
// Test a far call procedure with a calling convention PHI into ROM // Test a procedure with calling convention PHI - case #2
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-2-close-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_rom_finalize // [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main: plus_from_main:
jsr $ff6e lda #1
.byte <plus sta.z 0
.byte >plus pha
.byte 1 jsr plus
pla
sta.z 0
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
@@ -192,8 +200,8 @@ main: {
// [3] return // [3] return
rts rts
} }
.segment RAM_Bank1
// plus // plus
// test rom bank
// char plus(char a, char b) // char plus(char a, char b)
plus: { plus: {
.const a = '0' .const a = '0'
@@ -232,32 +240,39 @@ __constant char plus::return#1 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 24 Score: 39
// File Comments // File Comments
// Test a far call procedure with a calling convention PHI into ROM // Test a procedure with calling convention PHI - case #2
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-2-close-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_rom_finalize // [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
jsr $ff6e lda #1
.byte <plus sta.z 0
.byte >plus pha
.byte 1 jsr plus
pla
sta.z 0
// main::@1 // main::@1
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2
@@ -268,8 +283,8 @@ main: {
// [3] return // [3] return
rts rts
} }
.segment RAM_Bank1
// plus // plus
// test rom bank
// char plus(char a, char b) // char plus(char a, char b)
plus: { plus: {
.const a = '0' .const a = '0'

View File

@@ -0,0 +1,39 @@
// Test a procedure with calling convention PHI - case #2
.file [name="call-banked-phi-case-2-close-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,4 +1,4 @@
Loading link script "procedure-callingconvention-phi-bank.ld" Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@@ -144,6 +144,7 @@ char plus::return
Initial phi equivalence classes Initial phi equivalence classes
Complete equivalence classes Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
@@ -151,35 +152,42 @@ Uplift Scope [main]
Uplift Scope [plus] Uplift Scope [plus]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 60 combination Uplifting [main] best 75 combination
Uplifting [plus] best 60 combination Uplifting [plus] best 75 combination
Uplifting [] best 60 combination Uplifting [] best 75 combination
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
// Test a far call procedure with a calling convention PHI // Test a procedure with calling convention PHI - case #2
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-2-close-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_rom_finalize // [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main: plus_from_main:
jsr $ff6e lda #1
.byte <plus sta.z 0
.byte >plus pha
.byte 2 jsr plus
pla
sta.z 0
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
@@ -192,8 +200,8 @@ main: {
// [3] return // [3] return
rts rts
} }
.segment RAM_Bank1
// plus // plus
// Test rom fragment
// char plus(char a, char b) // char plus(char a, char b)
plus: { plus: {
.const a = '0' .const a = '0'
@@ -232,32 +240,39 @@ __constant char plus::return#1 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 24 Score: 39
// File Comments // File Comments
// Test a far call procedure with a calling convention PHI // Test a procedure with calling convention PHI - case #2
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-2-close-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_rom_finalize // [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
jsr $ff6e lda #1
.byte <plus sta.z 0
.byte >plus pha
.byte 2 jsr plus
pla
sta.z 0
// main::@1 // main::@1
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2
@@ -268,8 +283,8 @@ main: {
// [3] return // [3] return
rts rts
} }
.segment RAM_Bank1
// plus // plus
// Test rom fragment
// char plus(char a, char b) // char plus(char a, char b)
plus: { plus: {
.const a = '0' .const a = '0'

View File

@@ -0,0 +1,47 @@
// Test a procedure with calling convention PHI - case #3
.file [name="call-banked-phi-case-3-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr min
// }
rts
}
.segment Code
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -5,7 +5,7 @@ main: scope:[main] from
[1] call plus [1] call plus
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [2] *SCREEN = min::return#1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[3] return [3] return
@@ -14,7 +14,16 @@ main::@return: scope:[main] from main::@1
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main
[4] phi() [4] phi()
[5] call min
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [6] return
to:@return
char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return to:@return

View File

@@ -1,4 +1,4 @@
Loading link script "procedure-callingconvention-phi-bank.ld" Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@@ -22,15 +22,35 @@ __bank(bank) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 ) plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#1 = phi( main/plus::a#0 )
plus::$0 = plus::a#1 + plus::b#1 min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0 plus::return#1 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus/plus::return#1 ) plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4 plus::return#2 = plus::return#4
return return
to:@return to:@return
char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start() void __start()
__start: scope:[__start] from __start: scope:[__start] from
call main call main
@@ -46,6 +66,20 @@ __constant char * const SCREEN = (char *)$400
void __start() void __start()
void main() void main()
char main::$0 char main::$0
char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
@@ -74,14 +108,21 @@ Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start Removing unused procedure __start
@@ -89,27 +130,40 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [5] plus::return#1 = plus::a#0 + plus::b#0 Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation Successful SSA optimization Pass2ConstantRValueConsolidation
Constant plus::return#1 = plus::a#0+plus::b#0 Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1 Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0 Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings plus::return#0 Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = plus::return#1 Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = plus::return#1 Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@@ -119,7 +173,7 @@ main: scope:[main] from
[1] call plus [1] call plus
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [2] *SCREEN = min::return#1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[3] return [3] return
@@ -128,14 +182,27 @@ main::@return: scope:[main] from main::@1
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main
[4] phi() [4] phi()
[5] call min
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [6] return
to:@return
char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
void main() void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
char plus::a char plus::a
char plus::b char plus::b
@@ -144,47 +211,57 @@ char plus::return
Initial phi equivalence classes Initial phi equivalence classes
Complete equivalence classes Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [plus] Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 60 combination Uplifting [main] best 90 combination
Uplifting [plus] best 60 combination Uplifting [plus] best 90 combination
Uplifting [] best 60 combination Uplifting [min] best 90 combination
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
// Test a far call procedure with a calling convention PHI // Test a procedure with calling convention PHI - case #3
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-3-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_ram_finalize // [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main: plus_from_main:
jsr $ff6e lda #1
.byte <plus sta.z 0
.byte >plus pha
.byte 1 jsr plus
pla
sta.z 0
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #plus.return lda #min.return
sta SCREEN sta SCREEN
jmp __breturn jmp __breturn
// main::@return // main::@return
@@ -192,16 +269,31 @@ main: {
// [3] return // [3] return
rts rts
} }
.segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // char plus(char a, char b)
plus: { plus: {
.const a = '0' .label a = '0'
.const b = 7 .label b = 7
.label return = a+b // [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
min_from_plus:
jsr min
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [5] return // [6] return
rts
}
.segment Code
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts rts
} }
// File Data // File Data
@@ -210,71 +302,99 @@ ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a __constant char plus::a#0 = '0' // a
char plus::b char plus::b
__constant char plus::b#0 = 7 // b __constant char plus::b#0 = 7 // b
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 24 Score: 51
// File Comments // File Comments
// Test a far call procedure with a calling convention PHI // Test a procedure with calling convention PHI - case #3
// Upstart // Upstart
.cpu _65c02 .file [name="call-banked-phi-case-3-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, stage, platform"] .segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801] .segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d] .segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100] .segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100] .segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.segment stage .segment Code
// main // main
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_ram_finalize // [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
jsr $ff6e lda #1
.byte <plus sta.z 0
.byte >plus pha
.byte 1 jsr plus
pla
sta.z 0
// main::@1 // main::@1
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #plus.return lda #min.return
sta SCREEN sta SCREEN
// main::@return // main::@return
// } // }
// [3] return // [3] return
rts rts
} }
.segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // char plus(char a, char b)
plus: { plus: {
.const a = '0' .label a = '0'
.const b = 7 .label b = 7
.label return = a+b // min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
jsr min
// plus::@return // plus::@return
// [5] return // }
// [6] return
rts
}
.segment Code
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts rts
} }
// File Data // File Data

View File

@@ -1,10 +1,14 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a __constant char plus::a#0 = '0' // a
char plus::b char plus::b
__constant char plus::b#0 = 7 // b __constant char plus::b#0 = 7 // b
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return

View File

@@ -0,0 +1,47 @@
// Test a procedure with calling convention PHI - case #3
.file [name="call-banked-phi-case-3-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr min
// }
rts
}
.segment Code
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -5,7 +5,7 @@ main: scope:[main] from
[1] call plus [1] call plus
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#0 [2] *SCREEN = min::return#1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[3] return [3] return
@@ -14,7 +14,16 @@ main::@return: scope:[main] from main::@1
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main
[4] phi() [4] phi()
[5] call min
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [6] return
to:@return
char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return to:@return

View File

@@ -0,0 +1,401 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 90 combination
Uplifting [plus] best 90 combination
Uplifting [min] best 90 combination
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #3
// Upstart
.file [name="call-banked-phi-case-3-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
min_from_plus:
jsr min
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
.segment Code
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 51
// File Comments
// Test a procedure with calling convention PHI - case #3
// Upstart
.file [name="call-banked-phi-case-3-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
jsr min
// plus::@return
// }
// [6] return
rts
}
.segment Code
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -1,10 +1,14 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b) __bank(bank) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a __constant char plus::a#0 = '0' // a
char plus::b char plus::b
__constant char plus::b#0 = 7 // b __constant char plus::b#0 = 7 // b
char plus::return char plus::return
__constant char plus::return#0 = plus::a#0+plus::b#0 // return

View File

@@ -0,0 +1,46 @@
// Test a procedure with calling convention PHI - case #4
.file [name="call-banked-phi-case-4-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr min
// }
rts
}
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,399 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 90 combination
Uplifting [plus] best 90 combination
Uplifting [min] best 90 combination
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-4-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
min_from_plus:
jsr min
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 51
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-4-near-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
jsr min
// plus::@return
// }
// [6] return
rts
}
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -0,0 +1,46 @@
// Test a procedure with calling convention PHI - case #4
.file [name="call-banked-phi-case-4-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr min
// }
rts
}
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,399 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 90 combination
Uplifting [plus] best 90 combination
Uplifting [min] best 90 combination
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-4-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
min_from_plus:
jsr min
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 51
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-4-near-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call__phi_near_finalize
jsr min
// plus::@return
// }
// [6] return
rts
}
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -0,0 +1,50 @@
// Test a procedure with calling convention PHI - case #4
.file [name="call-banked-phi-case-5-far-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr $ff6e
.byte <min
.byte >min
.byte 2
// }
rts
}
.segment RAM_Bank2
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,407 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 90 combination
Uplifting [plus] best 90 combination
Uplifting [min] best 90 combination
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-5-far-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_ram_phi_far_finalize
min_from_plus:
jsr $ff6e
.byte <min
.byte >min
.byte 2
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
.segment RAM_Bank2
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 51
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-5-far-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_ram_phi_far_finalize
jsr $ff6e
.byte <min
.byte >min
.byte 2
// plus::@return
// }
// [6] return
rts
}
.segment RAM_Bank2
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -0,0 +1,50 @@
// Test a procedure with calling convention PHI - case #4
.file [name="call-banked-phi-case-5-far-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
jsr $ff6e
.byte <min
.byte >min
.byte 2
// }
rts
}
.segment RAM_Bank2
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,407 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 90 combination
Uplifting [plus] best 90 combination
Uplifting [min] best 90 combination
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-5-far-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_ram_phi_far_finalize
min_from_plus:
jsr $ff6e
.byte <min
.byte >min
.byte 2
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
.segment RAM_Bank2
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 51
// File Comments
// Test a procedure with calling convention PHI - case #4
// Upstart
.file [name="call-banked-phi-case-5-far-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_ram_phi_far_finalize
jsr $ff6e
.byte <min
.byte >min
.byte 2
// plus::@return
// }
// [6] return
rts
}
.segment RAM_Bank2
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -0,0 +1,52 @@
// Test a procedure with calling convention PHI - case #6
.file [name="call-banked-phi-case-6-close-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
lda #1
sta.z 1
pha
jsr min
pla
sta.z 1
// }
rts
}
.segment ROM_Bank1
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,412 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [5] call min [ ] ( plus:1 [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 105 combination
Uplifting [plus] best 105 combination
Uplifting [min] best 105 combination
Uplifting [] best 105 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #6
// Upstart
.file [name="call-banked-phi-case-6-close-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_rom_phi_close_finalize
min_from_plus:
lda #1
sta.z 1
pha
jsr min
pla
sta.z 1
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
.segment ROM_Bank1
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 66
// File Comments
// Test a procedure with calling convention PHI - case #6
// Upstart
.file [name="call-banked-phi-case-6-close-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_rom_phi_close_finalize
lda #1
sta.z 1
pha
jsr min
pla
sta.z 1
// plus::@return
// }
// [6] return
rts
}
.segment ROM_Bank1
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -0,0 +1,52 @@
// Test a procedure with calling convention PHI - case #6
.file [name="call-banked-phi-case-6-close-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
.label SCREEN = $400
.segment Code
main: {
// plus('0', 7)
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN
// }
rts
}
.segment RAM_Bank1
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
lda #1
sta.z 1
pha
jsr min
pla
sta.z 1
// }
rts
}
.segment ROM_Bank1
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
rts
}

View File

@@ -0,0 +1,29 @@
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return

View File

@@ -0,0 +1,412 @@
Loading link script "call-banked-phi.ld"
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#0 = plus::return#2
to:main::@1
main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 )
main::$0 = plus::return#3
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
min::a#0 = plus::a#1
min::b#0 = plus::b#1
call min
min::return#0 = min::return#2
to:plus::@1
plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 )
plus::$0 = min::return#3
plus::return#1 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 )
plus::return#2 = plus::return#4
return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
min::b#1 = phi( plus/min::b#0 )
min::a#1 = phi( plus/min::a#0 )
min::$0 = min::a#1 + min::b#1
min::return#1 = min::$0
to:min::@return
min::@return: scope:[min] from min
min::return#4 = phi( min/min::return#1 )
min::return#2 = min::return#4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char min(char a , char b)
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3
Alias min::return#0 = min::return#3
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2
Alias min::return#1 = min::$0 min::return#4 min::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Constant min::a#0 = plus::a#0
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant min::return#1 = min::a#0+min::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant min::return#0 = min::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#1 = min::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH
Calls in [main] to plus:1
Calls in [plus] to min:5
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
[5] call min
to:plus::@return
plus::@return: scope:[plus] from plus
[6] return
to:@return
__bank(bank) char min(char a , char b)
min: scope:[min] from plus
[7] phi()
to:min::@return
min::@return: scope:[min] from min
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [5] call min [ ] ( plus:1 [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 105 combination
Uplifting [plus] best 105 combination
Uplifting [min] best 105 combination
Uplifting [] best 105 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI - case #6
// Upstart
.file [name="call-banked-phi-case-6-close-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
plus_from_main:
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_rom_phi_close_finalize
min_from_plus:
lda #1
sta.z 1
pha
jsr min
pla
sta.z 1
jmp __breturn
// plus::@return
__breturn:
// [6] return
rts
}
.segment ROM_Bank1
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
jmp __breturn
// min::@return
__breturn:
// [8] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction min_from_plus:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
FINAL ASSEMBLER
Score: 66
// File Comments
// Test a procedure with calling convention PHI - case #6
// Upstart
.file [name="call-banked-phi-case-6-close-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef RAM_Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef RAM_Bank2 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef ROM_Bank1 [start=$C000, min=$C000, max=$FFFF, align=$100]
.segment Basic
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_cx16_ram_phi_close_finalize
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.label a = '0'
.label b = 7
// min(a, b)
// [5] call min
// [7] phi from plus to min [phi:plus->min] -- call_cx16_rom_phi_close_finalize
lda #1
sta.z 1
pha
jsr min
pla
sta.z 1
// plus::@return
// }
// [6] return
rts
}
.segment ROM_Bank1
// min
// char min(char a, char b)
min: {
.label return = plus.a+plus.b
// min::@return
// [8] return
rts
}
// File Data

View File

@@ -0,0 +1,14 @@
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char min(char a , char b)
char min::a
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return

View File

@@ -1,28 +0,0 @@
// Test a procedure with calling convention PHI
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.label SCREEN = $400
.segment stage
main: {
// plus('0', 7)
jsr plus
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,31 +0,0 @@
// Test a far call procedure with a calling convention PHI
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.label SCREEN = $400
.segment stage
main: {
// plus('0', 7)
jsr $ff6e
.byte <plus
.byte >plus
.byte 1
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,32 +0,0 @@
// Test a far call procedure with a calling convention PHI into ROM
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.label SCREEN = $400
.segment stage
main: {
// plus('0', 7)
jsr $ff6e
.byte <plus
.byte >plus
.byte 1
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
// test rom bank
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,32 +0,0 @@
// Test a far call procedure with a calling convention PHI
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.label SCREEN = $400
.segment stage
main: {
// plus('0', 7)
jsr $ff6e
.byte <plus
.byte >plus
.byte 2
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
// Test rom fragment
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,31 +0,0 @@
// Test a far call procedure with a calling convention phi
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.label SCREEN = $400
.segment stage
main: {
// plus('0', 7)
jsr $ff6e
.byte <plus
.byte >plus
.byte $14
// SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN
// }
rts
}
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}

View File

@@ -1,281 +0,0 @@
Loading link script "procedure-callingconvention-phi-bank.ld"
CONTROL FLOW GRAPH SSA
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
plus::b#1 = phi( main/plus::b#0 )
plus::a#1 = phi( main/plus::a#0 )
plus::$0 = plus::a#1 + plus::b#1
plus::return#0 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus
plus::return#3 = phi( plus/plus::return#0 )
plus::return#1 = plus::return#3
return
to:@return
void main()
main: scope:[main] from __start
plus::a#0 = '0'
plus::b#0 = 7
call plus
plus::return#2 = plus::return#1
to:main::@1
main::@1: scope:[main] from main
plus::return#4 = phi( main/plus::return#2 )
main::$0 = plus::return#4
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void main()
char main::$0
__bank(bank) char plus(char a , char b)
char plus::$0
char plus::a
char plus::a#0
char plus::a#1
char plus::b
char plus::b#0
char plus::b#1
char plus::return
char plus::return#0
char plus::return#1
char plus::return#2
char plus::return#3
char plus::return#4
Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::$0 plus::return#3 plus::return#1
Alias plus::return#2 = plus::return#4
Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0'
Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [8] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [0] plus::return#0 = plus::a#0 + plus::b#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant plus::return#0 = plus::a#0+plus::b#0
Successful SSA optimization Pass2ConstantIdentification
Constant plus::return#2 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#2
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings plus::return#2
Constant inlined plus::return#2 = plus::return#0
Constant inlined main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
CALL GRAPH
Calls in [main] to plus:1
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Adding NOP phi() at start of main
Adding NOP phi() at start of plus
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = plus::return#0
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
__bank(bank) char plus(char a , char b)
plus: scope:[plus] from main
[4] phi()
to:plus::@return
plus::@return: scope:[plus] from plus
[5] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
__bank(bank) char plus(char a , char b)
char plus::a
char plus::b
char plus::return
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] *SCREEN = plus::return#0 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [plus]
Uplift Scope [main]
Uplift Scope []
Uplifting [plus] best 60 combination
Uplifting [main] best 60 combination
Uplifting [] best 60 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a far call procedure with a calling convention phi
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
// Global Constants & labels
.label SCREEN = $400
.segment stage
// main
main: {
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_ram_finalize
plus_from_main:
jsr $ff6e
.byte <plus
.byte >plus
.byte $14
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = plus::return#0 -- _deref_pbuc1=vbuc2
lda #plus.return
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
// plus
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
jmp __breturn
// plus::@return
__breturn:
// [5] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void main()
__bank(bank) char plus(char a , char b)
char plus::a
__constant char plus::a#0 = '0' // a
char plus::b
__constant char plus::b#0 = 7 // b
char plus::return
__constant char plus::return#0 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER
Score: 24
// File Comments
// Test a far call procedure with a calling convention phi
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
// Global Constants & labels
.label SCREEN = $400
.segment stage
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_ram_finalize
jsr $ff6e
.byte <plus
.byte >plus
.byte $14
// main::@1
// SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#0 -- _deref_pbuc1=vbuc2
lda #plus.return
sta SCREEN
// main::@return
// }
// [3] return
rts
}
// plus
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
// plus::@return
// [5] return
rts
}
// File Data

View File

@@ -1,312 +0,0 @@
// The linker specification of the different segments.
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, Bank1, Bank2"]
.segmentdef Basic [start=$0801]a
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
.segmentdef Bank2 [start=$C000, min=$C000, max=$FFFF, align=$100]
// The target computer platform is the Commander X16,
// which implements banking in ram between 0xA0000 and 0xBFFF,
// and in rom between 0xC000 and 0xFFFF.
.label SCREEN = $400
.segment Code
// Practically this means that the main() function is placed in main memory ...
main: {
// func_ram_bank1_a('0', 7)
lda #7
ldx #'0'
jsr $ff6e
.byte <func_ram_bank1_a
.byte >func_ram_bank1_a
.byte 1
// func_ram_bank1_a('0', 7)
// SCREEN[0] = func_ram_bank1_a('0', 7)
sta SCREEN
// func_ram_bank1_b('0', 7)
jsr func_ram_bank1_b
// SCREEN[0] = func_ram_bank1_b('0', 7)
// Banked call to ram in bank 1 from main memory.
lda #func_ram_bank1_b.return
sta SCREEN
// func_ram_bank1_c('0', 7)
jsr $ff6e
.byte <func_ram_bank1_c
.byte >func_ram_bank1_c
.byte 1
// func_ram_bank1_c('0', 7)
// SCREEN[0] = func_ram_bank1_c('0', 7)
// Banked call to ram in bank 1 from main memory.
sta SCREEN
// func_ram_bank1_d('0', 7)
jsr $ff6e
.byte <func_ram_bank1_d
.byte >func_ram_bank1_d
.byte 1
// func_ram_bank1_d('0', 7)
// SCREEN[0] = func_ram_bank1_d('0', 7)
// Banked call to ram in bank 1 from main memory.
sta SCREEN
// func_ram_bank1_e('0', 7)
ldx #7
lda #'0'
jsr $ff6e
.byte <func_ram_bank1_e
.byte >func_ram_bank1_e
.byte 1
// func_ram_bank1_e('0', 7)
// SCREEN[0] = func_ram_bank1_e('0', 7)
// Banked call to ram in bank 1 from main memory.
sta SCREEN
// func_ram_bank1_f('0', 7)
jsr $ff6e
.byte <func_ram_bank1_f
.byte >func_ram_bank1_f
.byte 1
// func_ram_bank1_f('0', 7)
// SCREEN[0] = func_ram_bank1_f('0', 7)
// Banked call to ram in bank 1 from main memory.
sta SCREEN
// func_rom_bank2_a('0', 7)
lda #7
ldx #'0'
jsr $ff6e
.byte <func_rom_bank2_a
.byte >func_rom_bank2_a
.byte 2
// func_rom_bank2_a('0', 7)
// SCREEN[0] = func_rom_bank2_a('0', 7)
// Banked call to ram in bank 1 from main memory.
sta SCREEN
// func_rom_bank2_b('0', 7)
ldx #7
lda #'0'
jsr func_rom_bank2_b
// func_rom_bank2_b('0', 7)
// SCREEN[0] = func_rom_bank2_b('0', 7)
// Banked call to rom in bank 2 from main memory.
sta SCREEN
// func_rom_bank2_c('0', 7)
jsr $ff6e
.byte <func_rom_bank2_c
.byte >func_rom_bank2_c
.byte 2
// func_rom_bank2_c('0', 7)
// SCREEN[0] = func_rom_bank2_c('0', 7)
// Banked call to rom in bank 2 from main memory.
sta SCREEN
// func_rom_bank2_d('0', 7)
jsr $ff6e
.byte <func_rom_bank2_d
.byte >func_rom_bank2_d
.byte 2
// func_rom_bank2_d('0', 7)
// SCREEN[0] = func_rom_bank2_d('0', 7)
// Banked call to rom in bank 2 from main memory.
sta SCREEN
// func_rom_bank2_e('0', 7)
ldx #7
lda #'0'
jsr $ff6e
.byte <func_rom_bank2_e
.byte >func_rom_bank2_e
.byte 2
// func_rom_bank2_e('0', 7)
// SCREEN[0] = func_rom_bank2_e('0', 7)
// Banked call to rom in bank 2 from main memory.
sta SCREEN
// func_rom_bank2_f('0', 7)
jsr $ff6e
.byte <func_rom_bank2_f
.byte >func_rom_bank2_f
.byte 2
// func_rom_bank2_f('0', 7)
// SCREEN[0] = func_rom_bank2_f('0', 7)
// banked call to rom in bank 2 from main memory.
sta SCREEN
// func_main_a('0', 7)
ldx #7
lda #'0'
jsr func_main_a
// func_main_a('0', 7)
// SCREEN[0] = func_main_a('0', 7)
// banked call to rom in bank 2 from main memory.
sta SCREEN
// func_main_b('0', 7)
jsr func_main_b
// func_main_b('0', 7)
// SCREEN[0] = func_main_b('0', 7)
// Near call in main memory from main memory.
sta SCREEN
// }
rts
}
.segment Bank1
// Functional code
// __register(A) char func_ram_bank1_a(__register(X) char a, __register(A) char b)
func_ram_bank1_a: {
// a + b
stx.z $ff
clc
adc.z $ff
// }
rts
}
.segment Bank2
// The sequent functions will consider no banking calculations anymore.
// The __bank directive declares this function to be banked using call method ram in bank number 1 of banked ram.
// char func_ram_bank1_b(char a, char b)
func_ram_bank1_b: {
.const a = '0'
.const b = 7
.label return = a+b
rts
}
.segment Bank1
// __register(A) char func_ram_bank1_c(char a, char b)
func_ram_bank1_c: {
.const a = '0'
.const b = 7
// func_ram_bank1_a(a, b)
lda #b
ldx #a
jsr func_ram_bank1_a
// func_ram_bank1_a(a, b)
// }
rts
}
// __register(A) char func_ram_bank1_d(char a, char b)
func_ram_bank1_d: {
.const a = '0'
.const b = 7
// func_rom_bank2_a(a, b)
lda #b
ldx #a
jsr $ff6e
.byte <func_rom_bank2_a
.byte >func_rom_bank2_a
.byte 2
// func_rom_bank2_a(a, b)
// }
rts
}
// __register(A) char func_ram_bank1_e(__register(A) char a, __register(X) char b)
func_ram_bank1_e: {
// func_rom_bank2_b(a, b)
jsr func_rom_bank2_b
// func_rom_bank2_b(a, b)
// }
rts
}
// __register(A) char func_ram_bank1_f(char a, char b)
func_ram_bank1_f: {
.const a = '0'
.const b = 7
// func_main_a(a, b)
ldx #b
lda #a
jsr func_main_a
// func_main_a(a, b)
// }
rts
}
.segment Bank2
// The sequent functions will be banked using call method rom in bank number 2.
// __register(A) char func_rom_bank2_a(__register(X) char a, __register(A) char b)
func_rom_bank2_a: {
// a + b
stx.z $ff
clc
adc.z $ff
// }
rts
}
// The __bank directive declares this function to be banked using call method rom in bank number 2 of banked rom.
// __register(A) char func_rom_bank2_b(__register(A) char a, __register(X) char b)
func_rom_bank2_b: {
// a + b
stx.z $ff
clc
adc.z $ff
// }
rts
}
// __register(A) char func_rom_bank2_c(char a, char b)
func_rom_bank2_c: {
.const a = '0'
.const b = 7
// func_ram_bank1_a(a, b)
lda #b
ldx #a
jsr $ff6e
.byte <func_ram_bank1_a
.byte >func_ram_bank1_a
.byte 1
// func_ram_bank1_a(a, b)
// }
rts
}
// __register(A) char func_rom_bank2_d(char a, char b)
func_rom_bank2_d: {
.const a = '0'
.const b = 7
// func_rom_bank2_a(a, b)
lda #b
ldx #a
jsr func_rom_bank2_a
// func_rom_bank2_a(a, b)
// }
rts
}
// __register(A) char func_rom_bank2_e(__register(A) char a, __register(X) char b)
func_rom_bank2_e: {
// func_rom_bank2_b(a, b)
jsr func_rom_bank2_b
// func_rom_bank2_b(a, b)
// }
rts
}
// __register(A) char func_rom_bank2_f(char a, char b)
func_rom_bank2_f: {
.const a = '0'
.const b = 7
// func_main_a(a, b)
ldx #b
lda #a
jsr func_main_a
// func_main_a(a, b)
// }
rts
}
.segment Code
// The sequent functions will be addressed in the default main memory location (segment Code).
// Allocated in main memory.
// __register(A) char func_main_a(__register(A) char a, __register(X) char b)
func_main_a: {
// func_ram_bank1_e(a, b)
jsr $ff6e
.byte <func_ram_bank1_e
.byte >func_ram_bank1_e
.byte 1
// func_ram_bank1_e(a, b)
// }
rts
}
// Allocated in main memory.
// __register(A) char func_main_b(char a, char b)
func_main_b: {
.const a = '0'
.const b = 7
// func_rom_bank2_e(a, b)
ldx #b
lda #a
jsr $ff6e
.byte <func_rom_bank2_e
.byte >func_rom_bank2_e
.byte 2
// func_rom_bank2_e(a, b)
// }
rts
}

View File

@@ -1,267 +0,0 @@
void main()
main: scope:[main] from
[0] phi()
[1] call func_ram_bank1_a
[2] func_ram_bank1_a::return#4 = func_ram_bank1_a::return#0
to:main::@1
main::@1: scope:[main] from main
[3] main::$0 = func_ram_bank1_a::return#4
[4] *SCREEN = main::$0
[5] call func_ram_bank1_b
to:main::@2
main::@2: scope:[main] from main::@1
[6] *SCREEN = func_ram_bank1_b::return#0
[7] call func_ram_bank1_c
[8] func_ram_bank1_c::return#2 = func_ram_bank1_c::return#0
to:main::@3
main::@3: scope:[main] from main::@2
[9] main::$2 = func_ram_bank1_c::return#2
[10] *SCREEN = main::$2
[11] call func_ram_bank1_d
[12] func_ram_bank1_d::return#2 = func_ram_bank1_d::return#0
to:main::@4
main::@4: scope:[main] from main::@3
[13] main::$3 = func_ram_bank1_d::return#2
[14] *SCREEN = main::$3
[15] call func_ram_bank1_e
[16] func_ram_bank1_e::return#3 = func_ram_bank1_e::return#0
to:main::@5
main::@5: scope:[main] from main::@4
[17] main::$4 = func_ram_bank1_e::return#3
[18] *SCREEN = main::$4
[19] call func_ram_bank1_f
[20] func_ram_bank1_f::return#2 = func_ram_bank1_f::return#0
to:main::@6
main::@6: scope:[main] from main::@5
[21] main::$5 = func_ram_bank1_f::return#2
[22] *SCREEN = main::$5
[23] call func_rom_bank2_a
[24] func_rom_bank2_a::return#4 = func_rom_bank2_a::return#1
to:main::@7
main::@7: scope:[main] from main::@6
[25] main::$6 = func_rom_bank2_a::return#4
[26] *SCREEN = main::$6
[27] call func_rom_bank2_b
[28] func_rom_bank2_b::return#4 = func_rom_bank2_b::return#1
to:main::@8
main::@8: scope:[main] from main::@7
[29] main::$7 = func_rom_bank2_b::return#4
[30] *SCREEN = main::$7
[31] call func_rom_bank2_c
[32] func_rom_bank2_c::return#2 = func_rom_bank2_c::return#0
to:main::@9
main::@9: scope:[main] from main::@8
[33] main::$8 = func_rom_bank2_c::return#2
[34] *SCREEN = main::$8
[35] call func_rom_bank2_d
[36] func_rom_bank2_d::return#2 = func_rom_bank2_d::return#0
to:main::@10
main::@10: scope:[main] from main::@9
[37] main::$9 = func_rom_bank2_d::return#2
[38] *SCREEN = main::$9
[39] call func_rom_bank2_e
[40] func_rom_bank2_e::return#3 = func_rom_bank2_e::return#0
to:main::@11
main::@11: scope:[main] from main::@10
[41] main::$10 = func_rom_bank2_e::return#3
[42] *SCREEN = main::$10
[43] call func_rom_bank2_f
[44] func_rom_bank2_f::return#2 = func_rom_bank2_f::return#0
to:main::@12
main::@12: scope:[main] from main::@11
[45] main::$11 = func_rom_bank2_f::return#2
[46] *SCREEN = main::$11
[47] call func_main_a
[48] func_main_a::return#4 = func_main_a::return#2
to:main::@13
main::@13: scope:[main] from main::@12
[49] main::$12 = func_main_a::return#4
[50] *SCREEN = main::$12
[51] call func_main_b
[52] func_main_b::return#2 = func_main_b::return#0
to:main::@14
main::@14: scope:[main] from main::@13
[53] main::$13 = func_main_b::return#2
[54] *SCREEN = main::$13
to:main::@return
main::@return: scope:[main] from main::@14
[55] return
to:@return
__bank(bank) char func_ram_bank1_a(char a , char b)
func_ram_bank1_a: scope:[func_ram_bank1_a] from func_ram_bank1_c func_rom_bank2_c main
[56] func_ram_bank1_a::b#3 = phi( func_ram_bank1_c/func_ram_bank1_c::b#0, func_rom_bank2_c/func_rom_bank2_c::b#0, main/7 )
[56] func_ram_bank1_a::a#3 = phi( func_ram_bank1_c/func_ram_bank1_c::a#0, func_rom_bank2_c/func_rom_bank2_c::a#0, main/'0' )
[57] func_ram_bank1_a::return#0 = func_ram_bank1_a::a#3 + func_ram_bank1_a::b#3
to:func_ram_bank1_a::@return
func_ram_bank1_a::@return: scope:[func_ram_bank1_a] from func_ram_bank1_a
[58] return
to:@return
char func_ram_bank1_b(char a , char b)
func_ram_bank1_b: scope:[func_ram_bank1_b] from main::@1
[59] phi()
to:func_ram_bank1_b::@return
func_ram_bank1_b::@return: scope:[func_ram_bank1_b] from func_ram_bank1_b
[60] return
to:@return
__bank(bank) char func_ram_bank1_c(char a , char b)
func_ram_bank1_c: scope:[func_ram_bank1_c] from main::@2
[61] phi()
[62] call func_ram_bank1_a
[63] func_ram_bank1_a::return#2 = func_ram_bank1_a::return#0
to:func_ram_bank1_c::@1
func_ram_bank1_c::@1: scope:[func_ram_bank1_c] from func_ram_bank1_c
[64] func_ram_bank1_c::return#0 = func_ram_bank1_a::return#2
to:func_ram_bank1_c::@return
func_ram_bank1_c::@return: scope:[func_ram_bank1_c] from func_ram_bank1_c::@1
[65] return
to:@return
__bank(bank) char func_ram_bank1_d(char a , char b)
func_ram_bank1_d: scope:[func_ram_bank1_d] from main::@3
[66] phi()
[67] call func_rom_bank2_a
[68] func_rom_bank2_a::return#0 = func_rom_bank2_a::return#1
to:func_ram_bank1_d::@1
func_ram_bank1_d::@1: scope:[func_ram_bank1_d] from func_ram_bank1_d
[69] func_ram_bank1_d::return#0 = func_rom_bank2_a::return#0
to:func_ram_bank1_d::@return
func_ram_bank1_d::@return: scope:[func_ram_bank1_d] from func_ram_bank1_d::@1
[70] return
to:@return
__bank(bank) char func_ram_bank1_e(char a , char b)
func_ram_bank1_e: scope:[func_ram_bank1_e] from func_main_a main::@4
[71] func_ram_bank1_e::b#2 = phi( func_main_a/func_ram_bank1_e::b#0, main::@4/7 )
[71] func_ram_bank1_e::a#2 = phi( func_main_a/func_ram_bank1_e::a#0, main::@4/'0' )
[72] func_rom_bank2_b::a#0 = func_ram_bank1_e::a#2
[73] func_rom_bank2_b::b#0 = func_ram_bank1_e::b#2
[74] call func_rom_bank2_b
[75] func_rom_bank2_b::return#0 = func_rom_bank2_b::return#1
to:func_ram_bank1_e::@1
func_ram_bank1_e::@1: scope:[func_ram_bank1_e] from func_ram_bank1_e
[76] func_ram_bank1_e::return#0 = func_rom_bank2_b::return#0
to:func_ram_bank1_e::@return
func_ram_bank1_e::@return: scope:[func_ram_bank1_e] from func_ram_bank1_e::@1
[77] return
to:@return
__bank(bank) char func_ram_bank1_f(char a , char b)
func_ram_bank1_f: scope:[func_ram_bank1_f] from main::@5
[78] phi()
[79] call func_main_a
[80] func_main_a::return#0 = func_main_a::return#2
to:func_ram_bank1_f::@1
func_ram_bank1_f::@1: scope:[func_ram_bank1_f] from func_ram_bank1_f
[81] func_ram_bank1_f::return#0 = func_main_a::return#0
to:func_ram_bank1_f::@return
func_ram_bank1_f::@return: scope:[func_ram_bank1_f] from func_ram_bank1_f::@1
[82] return
to:@return
__bank(bank) char func_rom_bank2_a(char a , char b)
func_rom_bank2_a: scope:[func_rom_bank2_a] from func_ram_bank1_d func_rom_bank2_d main::@6
[83] func_rom_bank2_a::b#3 = phi( func_ram_bank1_d/func_ram_bank1_d::b#0, func_rom_bank2_d/func_rom_bank2_d::b#0, main::@6/7 )
[83] func_rom_bank2_a::a#3 = phi( func_ram_bank1_d/func_ram_bank1_d::a#0, func_rom_bank2_d/func_rom_bank2_d::a#0, main::@6/'0' )
[84] func_rom_bank2_a::return#1 = func_rom_bank2_a::a#3 + func_rom_bank2_a::b#3
to:func_rom_bank2_a::@return
func_rom_bank2_a::@return: scope:[func_rom_bank2_a] from func_rom_bank2_a
[85] return
to:@return
char func_rom_bank2_b(char a , char b)
func_rom_bank2_b: scope:[func_rom_bank2_b] from func_ram_bank1_e func_rom_bank2_e main::@7
[86] func_rom_bank2_b::b#3 = phi( func_ram_bank1_e/func_rom_bank2_b::b#0, func_rom_bank2_e/func_rom_bank2_b::b#1, main::@7/7 )
[86] func_rom_bank2_b::a#3 = phi( func_ram_bank1_e/func_rom_bank2_b::a#0, func_rom_bank2_e/func_rom_bank2_b::a#1, main::@7/'0' )
[87] func_rom_bank2_b::return#1 = func_rom_bank2_b::a#3 + func_rom_bank2_b::b#3
to:func_rom_bank2_b::@return
func_rom_bank2_b::@return: scope:[func_rom_bank2_b] from func_rom_bank2_b
[88] return
to:@return
__bank(bank) char func_rom_bank2_c(char a , char b)
func_rom_bank2_c: scope:[func_rom_bank2_c] from main::@8
[89] phi()
[90] call func_ram_bank1_a
[91] func_ram_bank1_a::return#3 = func_ram_bank1_a::return#0
to:func_rom_bank2_c::@1
func_rom_bank2_c::@1: scope:[func_rom_bank2_c] from func_rom_bank2_c
[92] func_rom_bank2_c::return#0 = func_ram_bank1_a::return#3
to:func_rom_bank2_c::@return
func_rom_bank2_c::@return: scope:[func_rom_bank2_c] from func_rom_bank2_c::@1
[93] return
to:@return
__bank(bank) char func_rom_bank2_d(char a , char b)
func_rom_bank2_d: scope:[func_rom_bank2_d] from main::@9
[94] phi()
[95] call func_rom_bank2_a
[96] func_rom_bank2_a::return#3 = func_rom_bank2_a::return#1
to:func_rom_bank2_d::@1
func_rom_bank2_d::@1: scope:[func_rom_bank2_d] from func_rom_bank2_d
[97] func_rom_bank2_d::return#0 = func_rom_bank2_a::return#3
to:func_rom_bank2_d::@return
func_rom_bank2_d::@return: scope:[func_rom_bank2_d] from func_rom_bank2_d::@1
[98] return
to:@return
__bank(bank) char func_rom_bank2_e(char a , char b)
func_rom_bank2_e: scope:[func_rom_bank2_e] from func_main_b main::@10
[99] func_rom_bank2_e::b#2 = phi( func_main_b/func_main_b::b#0, main::@10/7 )
[99] func_rom_bank2_e::a#2 = phi( func_main_b/func_main_b::a#0, main::@10/'0' )
[100] func_rom_bank2_b::a#1 = func_rom_bank2_e::a#2
[101] func_rom_bank2_b::b#1 = func_rom_bank2_e::b#2
[102] call func_rom_bank2_b
[103] func_rom_bank2_b::return#3 = func_rom_bank2_b::return#1
to:func_rom_bank2_e::@1
func_rom_bank2_e::@1: scope:[func_rom_bank2_e] from func_rom_bank2_e
[104] func_rom_bank2_e::return#0 = func_rom_bank2_b::return#3
to:func_rom_bank2_e::@return
func_rom_bank2_e::@return: scope:[func_rom_bank2_e] from func_rom_bank2_e::@1
[105] return
to:@return
__bank(bank) char func_rom_bank2_f(char a , char b)
func_rom_bank2_f: scope:[func_rom_bank2_f] from main::@11
[106] phi()
[107] call func_main_a
[108] func_main_a::return#1 = func_main_a::return#2
to:func_rom_bank2_f::@1
func_rom_bank2_f::@1: scope:[func_rom_bank2_f] from func_rom_bank2_f
[109] func_rom_bank2_f::return#0 = func_main_a::return#1
to:func_rom_bank2_f::@return
func_rom_bank2_f::@return: scope:[func_rom_bank2_f] from func_rom_bank2_f::@1
[110] return
to:@return
char func_main_a(char a , char b)
func_main_a: scope:[func_main_a] from func_ram_bank1_f func_rom_bank2_f main::@12
[111] func_main_a::b#3 = phi( func_ram_bank1_f/func_ram_bank1_f::b#0, func_rom_bank2_f/func_rom_bank2_f::b#0, main::@12/7 )
[111] func_main_a::a#3 = phi( func_ram_bank1_f/func_ram_bank1_f::a#0, func_rom_bank2_f/func_rom_bank2_f::a#0, main::@12/'0' )
[112] func_ram_bank1_e::a#0 = func_main_a::a#3
[113] func_ram_bank1_e::b#0 = func_main_a::b#3
[114] call func_ram_bank1_e
[115] func_ram_bank1_e::return#2 = func_ram_bank1_e::return#0
to:func_main_a::@1
func_main_a::@1: scope:[func_main_a] from func_main_a
[116] func_main_a::return#2 = func_ram_bank1_e::return#2
to:func_main_a::@return
func_main_a::@return: scope:[func_main_a] from func_main_a::@1
[117] return
to:@return
char func_main_b(char a , char b)
func_main_b: scope:[func_main_b] from main::@13
[118] phi()
[119] call func_rom_bank2_e
[120] func_rom_bank2_e::return#2 = func_rom_bank2_e::return#0
to:func_main_b::@1
func_main_b::@1: scope:[func_main_b] from func_main_b
[121] func_main_b::return#0 = func_rom_bank2_e::return#2
to:func_main_b::@return
func_main_b::@return: scope:[func_main_b] from func_main_b::@1
[122] return
to:@return

File diff suppressed because it is too large Load Diff

View File

@@ -1,204 +0,0 @@
__constant char * const SCREEN = (char *) 1024
char func_main_a(char a , char b)
char func_main_a::a
char func_main_a::a#3 // reg byte a 101.0
char func_main_a::b
char func_main_a::b#3 // reg byte x 50.5
char func_main_a::return
char func_main_a::return#0 // reg byte a 22.0
char func_main_a::return#1 // reg byte a 22.0
char func_main_a::return#2 // reg byte a 25.0
char func_main_a::return#4 // reg byte a 4.0
char func_main_b(char a , char b)
char func_main_b::a
__constant char func_main_b::a#0 = '0' // a
char func_main_b::b
__constant char func_main_b::b#0 = 7 // b
char func_main_b::return
char func_main_b::return#0 // reg byte a 4.333333333333333
char func_main_b::return#2 // reg byte a 4.0
__bank(bank) char func_ram_bank1_a(char a , char b)
char func_ram_bank1_a::a
char func_ram_bank1_a::a#3 // reg byte x 101.0
char func_ram_bank1_a::b
char func_ram_bank1_a::b#3 // reg byte a 101.0
char func_ram_bank1_a::return
char func_ram_bank1_a::return#0 // reg byte a 24.999999999999996
char func_ram_bank1_a::return#2 // reg byte a 22.0
char func_ram_bank1_a::return#3 // reg byte a 22.0
char func_ram_bank1_a::return#4 // reg byte a 4.0
char func_ram_bank1_b(char a , char b)
char func_ram_bank1_b::a
__constant char func_ram_bank1_b::a#0 = '0' // a
char func_ram_bank1_b::b
__constant char func_ram_bank1_b::b#0 = 7 // b
char func_ram_bank1_b::return
__constant char func_ram_bank1_b::return#0 = func_ram_bank1_b::a#0+func_ram_bank1_b::b#0 // return
__bank(bank) char func_ram_bank1_c(char a , char b)
char func_ram_bank1_c::a
__constant char func_ram_bank1_c::a#0 = '0' // a
char func_ram_bank1_c::b
__constant char func_ram_bank1_c::b#0 = 7 // b
char func_ram_bank1_c::return
char func_ram_bank1_c::return#0 // reg byte a 4.333333333333333
char func_ram_bank1_c::return#2 // reg byte a 4.0
__bank(bank) char func_ram_bank1_d(char a , char b)
char func_ram_bank1_d::a
__constant char func_ram_bank1_d::a#0 = '0' // a
char func_ram_bank1_d::b
__constant char func_ram_bank1_d::b#0 = 7 // b
char func_ram_bank1_d::return
char func_ram_bank1_d::return#0 // reg byte a 4.333333333333333
char func_ram_bank1_d::return#2 // reg byte a 4.0
__bank(bank) char func_ram_bank1_e(char a , char b)
char func_ram_bank1_e::a
char func_ram_bank1_e::a#0 // reg byte a 101.0
char func_ram_bank1_e::a#2 // reg byte a 1102.0
char func_ram_bank1_e::b
char func_ram_bank1_e::b#0 // reg byte x 202.0
char func_ram_bank1_e::b#2 // reg byte x 551.0
char func_ram_bank1_e::return
char func_ram_bank1_e::return#0 // reg byte a 276.0
char func_ram_bank1_e::return#2 // reg byte a 202.0
char func_ram_bank1_e::return#3 // reg byte a 4.0
__bank(bank) char func_ram_bank1_f(char a , char b)
char func_ram_bank1_f::a
__constant char func_ram_bank1_f::a#0 = '0' // a
char func_ram_bank1_f::b
__constant char func_ram_bank1_f::b#0 = 7 // b
char func_ram_bank1_f::return
char func_ram_bank1_f::return#0 // reg byte a 4.333333333333333
char func_ram_bank1_f::return#2 // reg byte a 4.0
__bank(bank) char func_rom_bank2_a(char a , char b)
char func_rom_bank2_a::a
char func_rom_bank2_a::a#3 // reg byte x 101.0
char func_rom_bank2_a::b
char func_rom_bank2_a::b#3 // reg byte a 101.0
char func_rom_bank2_a::return
char func_rom_bank2_a::return#0 // reg byte a 22.0
char func_rom_bank2_a::return#1 // reg byte a 25.0
char func_rom_bank2_a::return#3 // reg byte a 22.0
char func_rom_bank2_a::return#4 // reg byte a 4.0
char func_rom_bank2_b(char a , char b)
char func_rom_bank2_b::a
char func_rom_bank2_b::a#0 // reg byte a 1001.0
char func_rom_bank2_b::a#1 // reg byte a 101.0
char func_rom_bank2_b::a#3 // reg byte a 11103.0
char func_rom_bank2_b::b
char func_rom_bank2_b::b#0 // reg byte x 2002.0
char func_rom_bank2_b::b#1 // reg byte x 202.0
char func_rom_bank2_b::b#3 // reg byte x 11103.0
char func_rom_bank2_b::return
char func_rom_bank2_b::return#0 // reg byte a 2002.0
char func_rom_bank2_b::return#1 // reg byte a 2221.0
char func_rom_bank2_b::return#3 // reg byte a 202.0
char func_rom_bank2_b::return#4 // reg byte a 4.0
__bank(bank) char func_rom_bank2_c(char a , char b)
char func_rom_bank2_c::a
__constant char func_rom_bank2_c::a#0 = '0' // a
char func_rom_bank2_c::b
__constant char func_rom_bank2_c::b#0 = 7 // b
char func_rom_bank2_c::return
char func_rom_bank2_c::return#0 // reg byte a 4.333333333333333
char func_rom_bank2_c::return#2 // reg byte a 4.0
__bank(bank) char func_rom_bank2_d(char a , char b)
char func_rom_bank2_d::a
__constant char func_rom_bank2_d::a#0 = '0' // a
char func_rom_bank2_d::b
__constant char func_rom_bank2_d::b#0 = 7 // b
char func_rom_bank2_d::return
char func_rom_bank2_d::return#0 // reg byte a 4.333333333333333
char func_rom_bank2_d::return#2 // reg byte a 4.0
__bank(bank) char func_rom_bank2_e(char a , char b)
char func_rom_bank2_e::a
char func_rom_bank2_e::a#2 // reg byte a 101.0
char func_rom_bank2_e::b
char func_rom_bank2_e::b#2 // reg byte x 50.5
char func_rom_bank2_e::return
char func_rom_bank2_e::return#0 // reg byte a 28.5
char func_rom_bank2_e::return#2 // reg byte a 22.0
char func_rom_bank2_e::return#3 // reg byte a 4.0
__bank(bank) char func_rom_bank2_f(char a , char b)
char func_rom_bank2_f::a
__constant char func_rom_bank2_f::a#0 = '0' // a
char func_rom_bank2_f::b
__constant char func_rom_bank2_f::b#0 = 7 // b
char func_rom_bank2_f::return
char func_rom_bank2_f::return#0 // reg byte a 4.333333333333333
char func_rom_bank2_f::return#2 // reg byte a 4.0
void main()
char main::$0 // reg byte a 4.0
char main::$10 // reg byte a 4.0
char main::$11 // reg byte a 4.0
char main::$12 // reg byte a 4.0
char main::$13 // reg byte a 4.0
char main::$2 // reg byte a 4.0
char main::$3 // reg byte a 4.0
char main::$4 // reg byte a 4.0
char main::$5 // reg byte a 4.0
char main::$6 // reg byte a 4.0
char main::$7 // reg byte a 4.0
char main::$8 // reg byte a 4.0
char main::$9 // reg byte a 4.0
reg byte x [ func_ram_bank1_a::a#3 ]
reg byte a [ func_ram_bank1_a::b#3 ]
reg byte a [ func_ram_bank1_e::a#2 func_ram_bank1_e::a#0 ]
reg byte x [ func_ram_bank1_e::b#2 func_ram_bank1_e::b#0 ]
reg byte x [ func_rom_bank2_a::a#3 ]
reg byte a [ func_rom_bank2_a::b#3 ]
reg byte a [ func_rom_bank2_b::a#3 func_rom_bank2_b::a#0 func_rom_bank2_b::a#1 ]
reg byte x [ func_rom_bank2_b::b#3 func_rom_bank2_b::b#0 func_rom_bank2_b::b#1 ]
reg byte a [ func_rom_bank2_e::a#2 ]
reg byte x [ func_rom_bank2_e::b#2 ]
reg byte a [ func_main_a::a#3 ]
reg byte x [ func_main_a::b#3 ]
reg byte a [ func_ram_bank1_a::return#4 ]
reg byte a [ main::$0 ]
reg byte a [ func_ram_bank1_c::return#2 ]
reg byte a [ main::$2 ]
reg byte a [ func_ram_bank1_d::return#2 ]
reg byte a [ main::$3 ]
reg byte a [ func_ram_bank1_e::return#3 ]
reg byte a [ main::$4 ]
reg byte a [ func_ram_bank1_f::return#2 ]
reg byte a [ main::$5 ]
reg byte a [ func_rom_bank2_a::return#4 ]
reg byte a [ main::$6 ]
reg byte a [ func_rom_bank2_b::return#4 ]
reg byte a [ main::$7 ]
reg byte a [ func_rom_bank2_c::return#2 ]
reg byte a [ main::$8 ]
reg byte a [ func_rom_bank2_d::return#2 ]
reg byte a [ main::$9 ]
reg byte a [ func_rom_bank2_e::return#3 ]
reg byte a [ main::$10 ]
reg byte a [ func_rom_bank2_f::return#2 ]
reg byte a [ main::$11 ]
reg byte a [ func_main_a::return#4 ]
reg byte a [ main::$12 ]
reg byte a [ func_main_b::return#2 ]
reg byte a [ main::$13 ]
reg byte a [ func_ram_bank1_a::return#0 ]
reg byte a [ func_ram_bank1_a::return#2 ]
reg byte a [ func_ram_bank1_c::return#0 ]
reg byte a [ func_rom_bank2_a::return#0 ]
reg byte a [ func_ram_bank1_d::return#0 ]
reg byte a [ func_rom_bank2_b::return#0 ]
reg byte a [ func_ram_bank1_e::return#0 ]
reg byte a [ func_main_a::return#0 ]
reg byte a [ func_ram_bank1_f::return#0 ]
reg byte a [ func_rom_bank2_a::return#1 ]
reg byte a [ func_rom_bank2_b::return#1 ]
reg byte a [ func_ram_bank1_a::return#3 ]
reg byte a [ func_rom_bank2_c::return#0 ]
reg byte a [ func_rom_bank2_a::return#3 ]
reg byte a [ func_rom_bank2_d::return#0 ]
reg byte a [ func_rom_bank2_b::return#3 ]
reg byte a [ func_rom_bank2_e::return#0 ]
reg byte a [ func_main_a::return#1 ]
reg byte a [ func_rom_bank2_f::return#0 ]
reg byte a [ func_ram_bank1_e::return#2 ]
reg byte a [ func_main_a::return#2 ]
reg byte a [ func_rom_bank2_e::return#2 ]
reg byte a [ func_main_b::return#0 ]

View File

@@ -1,45 +0,0 @@
// Test a procedure with calling convention stack
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.const STACK_BASE = $103
.label SCREEN = $400
.segment stage
// __register(A) char plus(__zp(2) char a, __register(A) char b)
plus: {
.const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN_1 = 1
.label a = 2
tsx
lda STACK_BASE+OFFSET_STACK_A,x
sta.z a
tsx
lda STACK_BASE+OFFSET_STACK_B,x
// return a+b;
clc
adc.z a
// }
tsx
sta STACK_BASE+OFFSET_STACK_RETURN_1,x
rts
}
main: {
// plus('0', 7)
lda #'0'
pha
lda #7
pha
jsr plus
pla
pla
// SCREEN[0] = plus('0', 7)
sta SCREEN
// }
rts
}

View File

@@ -1,24 +0,0 @@
__stackcall char plus(char a , char b)
plus: scope:[plus] from
[0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A)
[1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B)
[2] plus::return#0 = plus::a#0 + plus::b#0
to:plus::@return
plus::@return: scope:[plus] from plus
[3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0
[4] return
to:@return
void main()
main: scope:[main] from
[5] stackpush(char) = '0'
[6] stackpush(char) = 7
[7] callexecute plus
sideeffect stackpullpadding(1)
[9] main::$0 = stackpull(char)
[10] *SCREEN = main::$0
to:main::@return
main::@return: scope:[main] from main
[11] return
to:@return

View File

@@ -1,350 +0,0 @@
Loading link script "procedure-callingconvention-stack-bank.ld"
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus('0', 7)
Calling convention STACK_CALL replacing param(plus::a) with stackidx(char,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(char,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return
Calling convention STACK_CALL adding stack pull main::$0 = stackpull(char)
Calling convention STACK_CALL adding stack push stackpush(char) = '0'
Calling convention STACK_CALL adding stack push stackpush(char) = 7
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
stackpush(char) = '0'
stackpush(char) = 7
callexecute plus
sideeffect stackpullpadding(1)
main::$0 = stackpull(char)
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main
return
to:@return
__stackcall char plus(char a , char b)
plus: scope:[plus] from
plus::a#0 = stackidx(char,plus::OFFSET_STACK_A)
plus::b#0 = stackidx(char,plus::OFFSET_STACK_B)
plus::$0 = plus::a#0 + plus::b#0
plus::return#0 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus
plus::return#1 = phi( plus/plus::return#0 )
stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#1
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
__constant unsigned int STACK_BASE = $103
void __start()
void main()
char main::$0
__stackcall char plus(char a , char b)
char plus::$0
__constant char plus::OFFSET_STACK_A = 1
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_1 = 1
char plus::a
char plus::a#0
char plus::b
char plus::b#0
char plus::return
char plus::return#0
char plus::return#1
Adding number conversion cast (unumber) 7 in stackpush(char) = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast stackpush(char) = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::$0 plus::return#1
Successful SSA optimization Pass2AliasElimination
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
CALL GRAPH
Calls in [main] to plus:7
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
__stackcall char plus(char a , char b)
plus: scope:[plus] from
[0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A)
[1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B)
[2] plus::return#0 = plus::a#0 + plus::b#0
to:plus::@return
plus::@return: scope:[plus] from plus
[3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0
[4] return
to:@return
void main()
main: scope:[main] from
[5] stackpush(char) = '0'
[6] stackpush(char) = 7
[7] callexecute plus
sideeffect stackpullpadding(1)
[9] main::$0 = stackpull(char)
[10] *SCREEN = main::$0
to:main::@return
main::@return: scope:[main] from main
[11] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
char main::$0 // 4.0
__stackcall char plus(char a , char b)
char plus::a
char plus::a#0 // 11.0
char plus::b
char plus::b#0 // 22.0
char plus::return
char plus::return#0 // 22.0
Initial phi equivalence classes
Added variable plus::a#0 to live range equivalence class [ plus::a#0 ]
Added variable plus::b#0 to live range equivalence class [ plus::b#0 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Complete equivalence classes
[ plus::a#0 ]
[ plus::b#0 ]
[ plus::return#0 ]
[ main::$0 ]
Allocated zp[1]:2 [ plus::b#0 ]
Allocated zp[1]:3 [ plus::return#0 ]
Allocated zp[1]:4 [ plus::a#0 ]
Allocated zp[1]:5 [ main::$0 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x
Statement [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x
Removing always clobbered register reg byte a as potential for zp[1]:4 [ plus::a#0 ]
Removing always clobbered register reg byte x as potential for zp[1]:4 [ plus::a#0 ]
Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a
Statement [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x
Statement [5] stackpush(char) = '0' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] stackpush(char) = 7 [ ] ( [ ] { } ) always clobbers reg byte a
Statement sideeffect stackpullpadding(1) always clobbers reg byte a
Statement [9] main::$0 = stackpull(char) [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a
Statement [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x
Statement [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x
Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a
Statement [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x
Statement [5] stackpush(char) = '0' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] stackpush(char) = 7 [ ] ( [ ] { } ) always clobbers reg byte a
Statement sideeffect stackpullpadding(1) always clobbers reg byte a
Statement [9] main::$0 = stackpull(char) [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a
Potential registers zp[1]:4 [ plus::a#0 ] : zp[1]:4 , reg byte y ,
Potential registers zp[1]:2 [ plus::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ plus::return#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [plus] 22: zp[1]:2 [ plus::b#0 ] 22: zp[1]:3 [ plus::return#0 ] 11: zp[1]:4 [ plus::a#0 ]
Uplift Scope [main] 4: zp[1]:5 [ main::$0 ]
Uplift Scope []
Uplifting [plus] best 79 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:4 [ plus::a#0 ]
Uplifting [main] best 73 combination reg byte a [ main::$0 ]
Uplifting [] best 73 combination
Attempting to uplift remaining variables inzp[1]:4 [ plus::a#0 ]
Uplifting [plus] best 73 combination zp[1]:4 [ plus::a#0 ]
Allocated (was zp[1]:4) zp[1]:2 [ plus::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention stack
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
// Global Constants & labels
.const STACK_BASE = $103
.label SCREEN = $400
.segment stage
// plus
// __register(A) char plus(__zp(2) char a, __register(A) char b)
plus: {
.const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN_1 = 1
.label a = 2
// [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_A,x
sta.z a
// [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_B,x
// [2] plus::return#0 = plus::a#0 + plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn
// plus::@return
__breturn:
// [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
tsx
sta STACK_BASE+OFFSET_STACK_RETURN_1,x
// [4] return
rts
}
// main
main: {
// [5] stackpush(char) = '0' -- _stackpushbyte_=vbuc1
lda #'0'
pha
// [6] stackpush(char) = 7 -- _stackpushbyte_=vbuc1
lda #7
pha
// [7] callexecute plus -- call_vprc1
jsr plus
// sideeffect stackpullpadding(1) -- _stackpullpadding_1
pla
// [9] main::$0 = stackpull(char) -- vbuaa=_stackpullbyte_
pla
// [10] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [11] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
__constant unsigned int STACK_BASE = $103
void main()
char main::$0 // reg byte a 4.0
__stackcall char plus(char a , char b)
__constant char plus::OFFSET_STACK_A = 1
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_1 = 1
char plus::a
char plus::a#0 // a zp[1]:2 11.0
char plus::b
char plus::b#0 // reg byte a 22.0
char plus::return
char plus::return#0 // reg byte a 22.0
zp[1]:2 [ plus::a#0 ]
reg byte a [ plus::b#0 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
FINAL ASSEMBLER
Score: 67
// File Comments
// Test a procedure with calling convention stack
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
// Global Constants & labels
.const STACK_BASE = $103
.label SCREEN = $400
.segment stage
// plus
// __register(A) char plus(__zp(2) char a, __register(A) char b)
plus: {
.const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN_1 = 1
.label a = 2
// [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_A,x
sta.z a
// [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_B,x
// return a+b;
// [2] plus::return#0 = plus::a#0 + plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// plus::@return
// }
// [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
tsx
sta STACK_BASE+OFFSET_STACK_RETURN_1,x
// [4] return
rts
}
// main
main: {
// plus('0', 7)
// [5] stackpush(char) = '0' -- _stackpushbyte_=vbuc1
lda #'0'
pha
// [6] stackpush(char) = 7 -- _stackpushbyte_=vbuc1
lda #7
pha
// [7] callexecute plus -- call_vprc1
jsr plus
// sideeffect stackpullpadding(1) -- _stackpullpadding_1
pla
// [9] main::$0 = stackpull(char) -- vbuaa=_stackpullbyte_
pla
// SCREEN[0] = plus('0', 7)
// [10] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN
// main::@return
// }
// [11] return
rts
}
// File Data

View File

@@ -1,19 +0,0 @@
__constant char * const SCREEN = (char *) 1024
__constant unsigned int STACK_BASE = $103
void main()
char main::$0 // reg byte a 4.0
__stackcall char plus(char a , char b)
__constant char plus::OFFSET_STACK_A = 1
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_1 = 1
char plus::a
char plus::a#0 // a zp[1]:2 11.0
char plus::b
char plus::b#0 // reg byte a 22.0
char plus::return
char plus::return#0 // reg byte a 22.0
zp[1]:2 [ plus::a#0 ]
reg byte a [ plus::b#0 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]

View File

@@ -1,45 +0,0 @@
// Test a procedure with calling convention stack
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
.const STACK_BASE = $103
.label SCREEN = $400
.segment stage
// __register(A) char plus(__zp(2) char a, __register(A) char b)
plus: {
.const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN_1 = 1
.label a = 2
tsx
lda STACK_BASE+OFFSET_STACK_A,x
sta.z a
tsx
lda STACK_BASE+OFFSET_STACK_B,x
// return a+b;
clc
adc.z a
// }
tsx
sta STACK_BASE+OFFSET_STACK_RETURN_1,x
rts
}
main: {
// plus('0', 7)
lda #'0'
pha
lda #7
pha
jsr plus
pla
pla
// SCREEN[0] = plus('0', 7)
sta SCREEN
// }
rts
}

View File

@@ -1,24 +0,0 @@
__stackcall char plus(char a , char b)
plus: scope:[plus] from
[0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A)
[1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B)
[2] plus::return#0 = plus::a#0 + plus::b#0
to:plus::@return
plus::@return: scope:[plus] from plus
[3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0
[4] return
to:@return
void main()
main: scope:[main] from
[5] stackpush(char) = '0'
[6] stackpush(char) = 7
[7] callexecute plus
sideeffect stackpullpadding(1)
[9] main::$0 = stackpull(char)
[10] *SCREEN = main::$0
to:main::@return
main::@return: scope:[main] from main
[11] return
to:@return

View File

@@ -1,350 +0,0 @@
Loading link script "procedure-callingconvention-stack-bank.ld"
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus('0', 7)
Calling convention STACK_CALL replacing param(plus::a) with stackidx(char,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(char,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return
Calling convention STACK_CALL adding stack pull main::$0 = stackpull(char)
Calling convention STACK_CALL adding stack push stackpush(char) = '0'
Calling convention STACK_CALL adding stack push stackpush(char) = 7
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
stackpush(char) = '0'
stackpush(char) = 7
callexecute plus
sideeffect stackpullpadding(1)
main::$0 = stackpull(char)
SCREEN[0] = main::$0
to:main::@return
main::@return: scope:[main] from main
return
to:@return
__stackcall char plus(char a , char b)
plus: scope:[plus] from
plus::a#0 = stackidx(char,plus::OFFSET_STACK_A)
plus::b#0 = stackidx(char,plus::OFFSET_STACK_B)
plus::$0 = plus::a#0 + plus::b#0
plus::return#0 = plus::$0
to:plus::@return
plus::@return: scope:[plus] from plus
plus::return#1 = phi( plus/plus::return#0 )
stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#1
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
__constant unsigned int STACK_BASE = $103
void __start()
void main()
char main::$0
__stackcall char plus(char a , char b)
char plus::$0
__constant char plus::OFFSET_STACK_A = 1
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_1 = 1
char plus::a
char plus::a#0
char plus::b
char plus::b#0
char plus::return
char plus::return#0
char plus::return#1
Adding number conversion cast (unumber) 7 in stackpush(char) = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast stackpush(char) = (unumber)7
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::$0 plus::return#1
Successful SSA optimization Pass2AliasElimination
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
CALL GRAPH
Calls in [main] to plus:7
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
__stackcall char plus(char a , char b)
plus: scope:[plus] from
[0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A)
[1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B)
[2] plus::return#0 = plus::a#0 + plus::b#0
to:plus::@return
plus::@return: scope:[plus] from plus
[3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0
[4] return
to:@return
void main()
main: scope:[main] from
[5] stackpush(char) = '0'
[6] stackpush(char) = 7
[7] callexecute plus
sideeffect stackpullpadding(1)
[9] main::$0 = stackpull(char)
[10] *SCREEN = main::$0
to:main::@return
main::@return: scope:[main] from main
[11] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
char main::$0 // 4.0
__stackcall char plus(char a , char b)
char plus::a
char plus::a#0 // 11.0
char plus::b
char plus::b#0 // 22.0
char plus::return
char plus::return#0 // 22.0
Initial phi equivalence classes
Added variable plus::a#0 to live range equivalence class [ plus::a#0 ]
Added variable plus::b#0 to live range equivalence class [ plus::b#0 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Complete equivalence classes
[ plus::a#0 ]
[ plus::b#0 ]
[ plus::return#0 ]
[ main::$0 ]
Allocated zp[1]:2 [ plus::b#0 ]
Allocated zp[1]:3 [ plus::return#0 ]
Allocated zp[1]:4 [ plus::a#0 ]
Allocated zp[1]:5 [ main::$0 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x
Statement [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x
Removing always clobbered register reg byte a as potential for zp[1]:4 [ plus::a#0 ]
Removing always clobbered register reg byte x as potential for zp[1]:4 [ plus::a#0 ]
Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a
Statement [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x
Statement [5] stackpush(char) = '0' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] stackpush(char) = 7 [ ] ( [ ] { } ) always clobbers reg byte a
Statement sideeffect stackpullpadding(1) always clobbers reg byte a
Statement [9] main::$0 = stackpull(char) [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a
Statement [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { } ) always clobbers reg byte a reg byte x
Statement [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { } ) always clobbers reg byte a reg byte x
Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { } ) always clobbers reg byte a
Statement [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 [ ] ( plus:7 [ ] { } ) always clobbers reg byte x
Statement [5] stackpush(char) = '0' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] stackpush(char) = 7 [ ] ( [ ] { } ) always clobbers reg byte a
Statement sideeffect stackpullpadding(1) always clobbers reg byte a
Statement [9] main::$0 = stackpull(char) [ main::$0 ] ( [ main::$0 ] { } ) always clobbers reg byte a
Potential registers zp[1]:4 [ plus::a#0 ] : zp[1]:4 , reg byte y ,
Potential registers zp[1]:2 [ plus::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ plus::return#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [plus] 22: zp[1]:2 [ plus::b#0 ] 22: zp[1]:3 [ plus::return#0 ] 11: zp[1]:4 [ plus::a#0 ]
Uplift Scope [main] 4: zp[1]:5 [ main::$0 ]
Uplift Scope []
Uplifting [plus] best 79 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:4 [ plus::a#0 ]
Uplifting [main] best 73 combination reg byte a [ main::$0 ]
Uplifting [] best 73 combination
Attempting to uplift remaining variables inzp[1]:4 [ plus::a#0 ]
Uplifting [plus] best 73 combination zp[1]:4 [ plus::a#0 ]
Allocated (was zp[1]:4) zp[1]:2 [ plus::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention stack
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
// Global Constants & labels
.const STACK_BASE = $103
.label SCREEN = $400
.segment stage
// plus
// __register(A) char plus(__zp(2) char a, __register(A) char b)
plus: {
.const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN_1 = 1
.label a = 2
// [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_A,x
sta.z a
// [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_B,x
// [2] plus::return#0 = plus::a#0 + plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn
// plus::@return
__breturn:
// [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
tsx
sta STACK_BASE+OFFSET_STACK_RETURN_1,x
// [4] return
rts
}
// main
main: {
// [5] stackpush(char) = '0' -- _stackpushbyte_=vbuc1
lda #'0'
pha
// [6] stackpush(char) = 7 -- _stackpushbyte_=vbuc1
lda #7
pha
// [7] callexecute plus -- call_vprc1
jsr plus
// sideeffect stackpullpadding(1) -- _stackpullpadding_1
pla
// [9] main::$0 = stackpull(char) -- vbuaa=_stackpullbyte_
pla
// [10] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [11] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
__constant unsigned int STACK_BASE = $103
void main()
char main::$0 // reg byte a 4.0
__stackcall char plus(char a , char b)
__constant char plus::OFFSET_STACK_A = 1
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_1 = 1
char plus::a
char plus::a#0 // a zp[1]:2 11.0
char plus::b
char plus::b#0 // reg byte a 22.0
char plus::return
char plus::return#0 // reg byte a 22.0
zp[1]:2 [ plus::a#0 ]
reg byte a [ plus::b#0 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
FINAL ASSEMBLER
Score: 67
// File Comments
// Test a procedure with calling convention stack
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segmentdef stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, align=$100]
// Global Constants & labels
.const STACK_BASE = $103
.label SCREEN = $400
.segment stage
// plus
// __register(A) char plus(__zp(2) char a, __register(A) char b)
plus: {
.const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN_1 = 1
.label a = 2
// [0] plus::a#0 = stackidx(char,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_A,x
sta.z a
// [1] plus::b#0 = stackidx(char,plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+OFFSET_STACK_B,x
// return a+b;
// [2] plus::return#0 = plus::a#0 + plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// plus::@return
// }
// [3] stackidx(char,plus::OFFSET_STACK_RETURN_1) = plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
tsx
sta STACK_BASE+OFFSET_STACK_RETURN_1,x
// [4] return
rts
}
// main
main: {
// plus('0', 7)
// [5] stackpush(char) = '0' -- _stackpushbyte_=vbuc1
lda #'0'
pha
// [6] stackpush(char) = 7 -- _stackpushbyte_=vbuc1
lda #7
pha
// [7] callexecute plus -- call_vprc1
jsr plus
// sideeffect stackpullpadding(1) -- _stackpullpadding_1
pla
// [9] main::$0 = stackpull(char) -- vbuaa=_stackpullbyte_
pla
// SCREEN[0] = plus('0', 7)
// [10] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN
// main::@return
// }
// [11] return
rts
}
// File Data

View File

@@ -1,19 +0,0 @@
__constant char * const SCREEN = (char *) 1024
__constant unsigned int STACK_BASE = $103
void main()
char main::$0 // reg byte a 4.0
__stackcall char plus(char a , char b)
__constant char plus::OFFSET_STACK_A = 1
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_1 = 1
char plus::a
char plus::a#0 // a zp[1]:2 11.0
char plus::b
char plus::b#0 // reg byte a 22.0
char plus::return
char plus::return#0 // reg byte a 22.0
zp[1]:2 [ plus::a#0 ]
reg byte a [ plus::b#0 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]

Some files were not shown because too many files have changed in this diff Show More