1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +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="BANK1.BIN", type="bin", segments="Bank1"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=%P]
.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
:BasicUpstart(%E)
.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 <conio.h>
#include <printf.h>
#include <kernal.h>
#include "cx16-banking-1.h"
#include <cx16-kernal.h>
// The target computer platform is the Commander X16,
// 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
@ -157,24 +157,29 @@ Uplifting [] best 60 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a procedure with calling convention PHI
// Test a procedure with calling convention PHI - case #1
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// [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:
jsr plus
jmp __b1
@ -231,25 +236,30 @@ FINAL ASSEMBLER
Score: 24
// File Comments
// Test a procedure with calling convention PHI
// Test a procedure with calling convention PHI - case #1
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// plus('0', 7)
// [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
// main::@1
// 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
@ -144,6 +144,7 @@ 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 = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
@ -151,35 +152,42 @@ Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope []
Uplifting [main] best 60 combination
Uplifting [plus] best 60 combination
Uplifting [] best 60 combination
Uplifting [main] best 75 combination
Uplifting [plus] best 75 combination
Uplifting [] best 75 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a far call procedure with a calling convention PHI into ROM
// Test a procedure with calling convention PHI - case #2
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// [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:
jsr $ff6e
.byte <plus
.byte >plus
.byte 1
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
@ -192,8 +200,8 @@ main: {
// [3] return
rts
}
.segment RAM_Bank1
// plus
// test rom bank
// char plus(char a, char b)
plus: {
.const a = '0'
@ -232,32 +240,39 @@ __constant char plus::return#1 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER
Score: 24
Score: 39
// File Comments
// Test a far call procedure with a calling convention PHI into ROM
// Test a procedure with calling convention PHI - case #2
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_rom_finalize
jsr $ff6e
.byte <plus
.byte >plus
.byte 1
// [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 = plus::return#1 -- _deref_pbuc1=vbuc2
@ -268,8 +283,8 @@ main: {
// [3] return
rts
}
.segment RAM_Bank1
// plus
// test rom bank
// char plus(char a, char b)
plus: {
.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
@ -144,6 +144,7 @@ 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 = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
@ -151,35 +152,42 @@ Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope []
Uplifting [main] best 60 combination
Uplifting [plus] best 60 combination
Uplifting [] best 60 combination
Uplifting [main] best 75 combination
Uplifting [plus] best 75 combination
Uplifting [] best 75 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Test a far call procedure with a calling convention PHI
// Test a procedure with calling convention PHI - case #2
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// [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:
jsr $ff6e
.byte <plus
.byte >plus
.byte 2
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
@ -192,8 +200,8 @@ main: {
// [3] return
rts
}
.segment RAM_Bank1
// plus
// Test rom fragment
// char plus(char a, char b)
plus: {
.const a = '0'
@ -232,32 +240,39 @@ __constant char plus::return#1 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER
Score: 24
Score: 39
// File Comments
// Test a far call procedure with a calling convention PHI
// Test a procedure with calling convention PHI - case #2
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// plus('0', 7)
// [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_far_cx16_rom_finalize
jsr $ff6e
.byte <plus
.byte >plus
.byte 2
// [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 = plus::return#1 -- _deref_pbuc1=vbuc2
@ -268,8 +283,8 @@ main: {
// [3] return
rts
}
.segment RAM_Bank1
// plus
// Test rom fragment
// char plus(char a, char b)
plus: {
.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
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
@ -14,7 +14,16 @@ main::@return: scope:[main] from main::@1
__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
[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

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
@ -22,15 +22,35 @@ __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
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
plus::return#4 = phi( plus/plus::return#1 )
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
@ -46,6 +66,20 @@ __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
@ -74,14 +108,21 @@ 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
@ -89,27 +130,40 @@ 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 [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
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
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 plus::return#0
Constant inlined plus::return#0 = plus::return#1
Constant inlined main::$0 = plus::return#1
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
@ -119,7 +173,7 @@ main: scope:[main] from
[1] call plus
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
@ -128,14 +182,27 @@ main::@return: scope:[main] from main::@1
__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
[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
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
@ -144,47 +211,57 @@ char plus::return
Initial phi equivalence classes
Complete equivalence classes
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
Uplift Scope [main]
Uplift Scope [plus]
Uplift Scope [min]
Uplift Scope []
Uplifting [main] best 60 combination
Uplifting [plus] best 60 combination
Uplifting [] best 60 combination
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 far call procedure with a calling convention PHI
// Test a procedure with calling convention PHI - case #3
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// main
main: {
// [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:
jsr $ff6e
.byte <plus
.byte >plus
.byte 1
lda #1
sta.z 0
pha
jsr plus
pla
sta.z 0
jmp __b1
// main::@1
__b1:
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2
lda #plus.return
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2
lda #min.return
sta SCREEN
jmp __breturn
// main::@return
@ -192,16 +269,31 @@ main: {
// [3] return
rts
}
.segment RAM_Bank1
// plus
// char plus(char a, char b)
plus: {
.const a = '0'
.const b = 7
.label return = a+b
.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:
// [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
}
// File Data
@ -210,71 +302,99 @@ 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
__constant char plus::return#1 = plus::a#0+plus::b#0 // return
FINAL ASSEMBLER
Score: 24
Score: 51
// File Comments
// Test a far call procedure with a calling convention PHI
// Test a procedure with calling convention PHI - case #3
// Upstart
.cpu _65c02
.segmentdef Program [segments="Basic, Code, Data, stage, platform"]
.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 stage [start=$0400, min=$0400, max=$07FF, align=$100]
.segmentdef platform [start=$C000, min=$C000, max=$C7FF, 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
:BasicUpstart(main)
.segment Code
.segment Data
// Global Constants & labels
.label SCREEN = $400
.segment stage
.segment Code
// 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 1
// [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 = plus::return#1 -- _deref_pbuc1=vbuc2
lda #plus.return
// [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: {
.const a = '0'
.const b = 7
.label return = a+b
.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
// [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
}
// File Data

View File

@ -1,10 +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
__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#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
to:main::@1
main::@1: scope:[main] from main
[2] *SCREEN = plus::return#0
[2] *SCREEN = min::return#1
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
@ -14,7 +14,16 @@ main::@return: scope:[main] from main::@1
__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
[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

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
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
__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